home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
vbdatabs
/
winmain.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-17
|
122KB
|
3,972 lines
// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: winmain.cpp
// Compiler Used: MSVC40, HPUX CPP 10.24
// Produced By: Doug Gaer
// File Creation Date: 09/18/1997
// Date Last Modified: 03/18/1999
// Copyright (c) 1997 Douglas M. Gaer
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
All those who put this code or its derivatives in a commercial
product MUST mention this copyright in their documentation for
users of the products in which this code or its derivative
classes are used. Otherwise, you have the freedom to redistribute
verbatim copies of this source code, adapt it to your specific
needs, or improve the code and release your improvements to the
public provided that the modified files carry prominent notices
stating that you changed the files and the date of any change.
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.
This is a test program used to test the (P)ersistent base class
in a practical database application using the wxWindow GUI library
version 1.68
*/
// ----------------------------------------------------------- //
#include <stdlib.h> // Needed for getenv under HPUX CPP
#include "timer.h"
#include "dbconfig.h"
#include "winmain.h"
#include "strutil.h"
#include "asprint.h"
#include "vbdstats.h"
#include "btwalker.h"
// This struct was added to read Variable Block Headers because
// the Status member of VBHeader struct in the vbdfile.h file
// caused a syntax error when compiling this program under HPUX
// CPP version 1024.
struct VBlockHeader // (V)ariable (B)lock (H)eader
{
UINT32 CkWord; // (C)heck (W)ord for file integrity checks (4 bytes)
UINT32 Length; // Length of this block including VB header (4 bytes)
UINT32 VBStatus; // Status of dynamic data stored in VB (4 byte)
FAU NextDeletedVB; // Pointer to next deleted VB (4 bytes)
};
// (V)ariable (B)lock (D)atabse components
static POD *DB; // Global database pointer
Grocery *agrocery = 0; // Global data buffer used to add objects
Grocery *cgrocery = 0; // Global data buffer used to change objects
Grocery *dgrocery = 0; // Global data buffer used to display objects
const char *WildCard = "*"; // Used for wild card searches
// Define global field names for controls, displays, printing
const char *KeyName = "ITEM NAME";
const char *M2Name = "BRAND NAME";
const char *M3Name = "STORE NAME";
const char *M4Name = "PRICE";
const char *M5Name = "QUANTITY";
const char *M6Name = "PURCHASING";
const char *M7Name = "LINE TOTAL";
const char *M8Name = "GRAND TOTAL";
double grand_total = 0;
double sales_tax = 0;
// Set buffer length for formatting strings
const int sbuffer_len = 255;
// Output limit per string for ASCII printing
const int StringOffset = 15; // String limits
const int PrintColsSpec = 111; // Columns limits
// Global mode indicators used to select items to be purchased
int display_all = 0; // Display items for purchase only
int print_all = 0; // Print items for purchase only
int ps_print_all = 0; // PostScript print items for purchase only
int as_print_all = 0; // ASCII print items for purchase only
int view_all = 0; // View total cost of items for purchase only
int purchase_all = 1; // Used to set purchasing status
// Declare frame, subframe and menu objects
MyFrame *frame = 0;
wxMenuBar *menu_bar = 0;
wxFrame *APanelFrame = 0;
wxFrame *CPanelFrame = 0;
wxFrame *DPanelFrame = 0;
#ifdef __USE_MSW_PRINTING__
wxDialogBox *wxPageDialog = 0; // MSW page setup dialog box
MSWPrintingParameters MSWPrnPars;
MSWPrintingParameters *MSWPrintSetup = &MSWPrnPars;
const int mswpDocNameLen = 255;
char mswpDocumentName[mswpDocNameLen];
#endif // __USE_MSW_PRINTING__
// Variable used to print display list objects
int print_list = 0;
int num_objects = 0;
int displaying_list = 0;
// Font, Pen, and Cursor objects
wxFont *labelFont = 0;
wxFont *itemFont = 0;
wxFont *textWindowFont = 0;
// wxWindows control objects
wxButton *btn_add_add = 0; // Object Add Panel Add button
wxButton *btn_add_can = 0; // Object Add Panel Cancel button
wxButton *btn_add_close = 0; // Object Add Panel Close button
wxButton *btn_add_revert = 0; // Object Add Panel Revert button
wxChoice *add_PurchasingChoice = 0; // Add panel purchasing choice box
char *PurchasingChoiceStrings[2] = {
"No",
"Yes"
};
wxButton *btn_ch_sh = 0; // Objedct Change Panel Search button
wxButton *btn_ch_cm = 0; // Object Change Panel Commit button
wxButton *btn_ch_can = 0; // Object Change Panel Cancel button
wxButton *btn_ch_close = 0; // Object Change Panel Close button
wxButton *btn_ch_revert = 0; // Object Change Panel Revert button
wxChoice *ch_PurchasingChoice = 0; // Change panel purchasing choice box
wxButton *btn_ds_nx = 0; // Object Display Panel Next button
wxButton *btn_ds_prev = 0; // Object Display Panel Previous button
wxButton *btn_ds_ch = 0; // Object Display Panel Change button
wxButton *btn_ds_rm = 0; // Object Display Panel Remove button
wxButton *btn_ds_close = 0; // Object Display Panel Close button
#ifdef __USE_MSW_PRINTING__
wxButton *btn_pdb_close = 0; // MSW page setup dialog Close button
wxButton *btn_pdb_cancel = 0; // MSW page setup dialog Accept button
wxButton *btn_pdb_accept = 0; // MSW page setup dialog Accept button
wxButton *btn_pdb_default = 0; // MSW page setup dialog Default button
wxSlider *LppSlider = 0; // Lines per page slider
wxSlider *CellSlider = 0; // Cell width slider
wxSlider *FsSlider = 0; // Font size slider
wxSlider *LRMSlider = 0; // Left and right margin slider
wxChoice *OrientationChoice = 0; // Orientation choice box
char *OrChoiceStrings[2] = {
"Landscape",
"Portrait"
};
wxChoice *FontChoice = 0; // Font family choice box
char *FontChoiceStrings[6] = {
"Swiss", // wxSWISS
"Roman", // wxROMAN
"Decorative", // wxDECORATIVE
"Modern", // wxMODERN
"Script", // wxSCRIPT
"System" // wxDEFAULT
};
#endif // __USE_MSW_PRINTING__
// This statement initializes the whole application and calls OnInit
MyApp myApp;
// A macro needed for some compilers (AIX) that need 'main' to be defined
// in the application itself.
IMPLEMENT_WXWIN_MAIN
// `Main program' equivalent, creating windows and returning main app frame
wxFrame *MyApp::OnInit(void)
{
// Create the main frame window
frame = new MyFrame(NULL, (char *)ProgramName, 50, 50, 400, 300);
// Give this frame a status line
frame->CreateStatusLine(1);
// Give it an icon
#ifdef wx_msw
frame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
frame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
// File menu
wxMenu *file_menu = new wxMenu;
file_menu->Append(FILE_VBDSTATS, "VBD file &Stats",
"Display VBD file statistics");
file_menu->AppendSeparator();
file_menu->Append(FILE_EXPORT, "Export","Export database to ASCII file");
file_menu->Append(FILE_IMPORT, "Import", "Import ASCII file into database");
file_menu->Append(FILE_TEMPLATE, "Create Template",
"Create an ASCII template for import file");
file_menu->AppendSeparator();
file_menu->Append(FILE_BACKUP, "Backup",
"Backup the database to another file");
file_menu->Append(FILE_MERGE, "Merge",
"Merge the contents of another database file");
file_menu->AppendSeparator();
file_menu->Append(FILE_COMPARE_INDEX, "Compare Index File",
"Compare the index file to the database file");
file_menu->Append(FILE_REBUILD_INDEX, "Rebuild Index File",
"Rebuild the index file for this database");
file_menu->AppendSeparator();
file_menu->Append(FILE_QUIT, "E&xit","Exit this program");
// Edit menu
wxMenu *edit_menu = new wxMenu;
edit_menu->Append(EDIT_CUT, "Cut\tCtrl+X", "Cut text and copy to clipboard");
edit_menu->AppendSeparator();
edit_menu->Append(EDIT_COPY, "Copy\tCtrl+C", "Copy text to clipboard");
edit_menu->AppendSeparator();
edit_menu->Append(EDIT_PASTE, "Paste\tCtrl+V", "Paste text from clipboard");
// Database menu
wxMenu *db_menu = new wxMenu;
db_menu->Append(DB_DISPLAY_PURCHASING,
"&Display Objects to be Purchased",
"Display only objects selected for purchase ");
db_menu->AppendSeparator();
db_menu->Append(DB_DISPLAY_ALL, "Display All Objects",
"Display all objects in the database");
db_menu->AppendSeparator();
db_menu->Append(DB_ADD, "&Add", "Add objects to the database");
db_menu->AppendSeparator();
db_menu->Append(DB_CHANGE, "&Change", "Change an object in the database");
db_menu->AppendSeparator();
db_menu->Append(DB_REMOVE, "&Remove", "Remove an object from the database");
db_menu->AppendSeparator();
db_menu->Append(DB_RESET_PURCHASING, "Reset Purchasing List",
"Setting all objects for purchase to no");
db_menu->AppendSeparator();
db_menu->Append(DB_SET_ALL_PURCHASING, "Set All For Purchase",
"Purchase all the objects in the database");
// Find menu
wxMenu *find_menu = new wxMenu;
const char *Prompt = "Find by ";
UString s(Prompt); int PromptLen = strlen(Prompt); int StringLen = 0;
s = s + KeyName; StringLen = strlen(KeyName);
find_menu->Append(FIND_BYNAME, s.c_str(), s.c_str());
s.DeleteAt(PromptLen, StringLen);
find_menu->AppendSeparator();
s = s + M2Name; StringLen = strlen(M2Name);
find_menu->Append(FIND_BYBRAND, s.c_str(), s.c_str());
s.DeleteAt(PromptLen, StringLen);
find_menu->AppendSeparator();
s = s + M3Name; StringLen = strlen(M3Name);
find_menu->Append(FIND_BYSTORE, s.c_str(), s.c_str());
s.DeleteAt(PromptLen, StringLen);
// Print menu
wxMenu *print_menu = new wxMenu;
#ifdef __USE_MSW_PRINTING__
print_menu->Append(WXPRINT_PRINT_PURCHASING, "Print Objects to be Purchased",
"Print only the objects selected for purchase");
print_menu->Append(WXPRINT_PRINT_ALL, "Print All Objects",
"Print all objects to the selected printer");
print_menu->AppendSeparator();
print_menu->Append(WXPRINT_PRINTER_SETUP, "Printer Setup",
"Configure the seleted printer");
print_menu->Append(WXPRINT_PAGE_SETUP, "Page Setup",
"Set the page parameters before printing");
print_menu->AppendSeparator();
print_menu->Append(WXPRINT_PREVIEW_PURCHASING,
"Print Preview Objects for Purchase",
"Preview before printing objects for purchase");
print_menu->Append(WXPRINT_PREVIEW_ALL, "Print Preview for All Objects",
"Preview before printing all objects");
print_menu->AppendSeparator();
#endif // __USE_MSW_PRINTING__
print_menu->Append(PRINT_POSTSCRIPT_PURCHASING, "Print to PostScript file",
"Print objects for purchase to PostScript file");
print_menu->Append(PRINT_POSTSCRIPT_ALL,
"Print all Objects to PostScript file",
"Print all objects to a PostScript file");
print_menu->AppendSeparator();
print_menu->Append(PRINT_ASCII_PURCHASING, "Print to Text File",
"Print objects for purchase to text file");
print_menu->Append(PRINT_ASCII_ALL, "Print all Objects to Text File",
"Print all objects to a text file");
// View menu
wxMenu *view_menu = new wxMenu;
view_menu->Append(VIEW_CLEAR, "Clear Window", "Clear this text window");
view_menu->AppendSeparator();
view_menu->Append(VIEW_TOTAL_PURCHASING, "View Cost of Purchase",
"View total cost of objects selected for purchase");
view_menu->AppendSeparator();
view_menu->Append(VIEW_TOTAL_ALL, "View Cost All Objects",
"View total cost of all the objects");
// Help menu
wxMenu *help_menu = new wxMenu;
help_menu->Append(HELP_ABOUT, "&About", "Info about this program");
help_menu->AppendSeparator();
help_menu->Append(HELP_USERLEVEL, "Access Rights",
"Display your user access rights");
// Make all the menu bars
menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
menu_bar->Append(edit_menu, "&Edit");
menu_bar->Append(db_menu, "Data&base");
menu_bar->Append(find_menu, "F&ind");
menu_bar->Append(print_menu, "&Print");
menu_bar->Append(view_menu, "&View");
menu_bar->Append(help_menu, "&Help");
frame->SetMenuBar(menu_bar);
// Associate the menu bar with the frame
frame->SetMenuBar(menu_bar);
// Create a text window in the main frame
frame->textWin = new MyTextWindow(frame, 0, 250, 400, 250,
wxNATIVE_IMPL);
frame->textWin->DragAcceptFiles(TRUE);
// *********************************************************** //
// Object Add Panel Code Starts Here
// *********************************************************** //
frame->addText = new MyText; // Init MyText Class pointer
APanelFrame = new wxFrame(NULL, "Adding Object", 0, 0, 390, 390);
// Panel fonts
labelFont = new wxFont(12, wxSWISS, wxNORMAL, wxBOLD);
itemFont = new wxFont(11, wxSWISS, wxNORMAL, wxBOLD);
// Give it an icon
#ifdef wx_msw
APanelFrame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
APanelFrame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
int apfwidth, apfheight;
APanelFrame->GetClientSize(&apfwidth, &apfheight);
// Make a panel in the subframe
frame->apanel = new wxPanel(APanelFrame, 0, 0,
apfwidth, apfheight);
frame->apanel->SetLabelPosition(wxVERTICAL);
frame->apanel->SetLabelFont(labelFont);
frame->apanel->SetButtonFont(itemFont);
frame->apanel->SetFont(itemFont);
// Needed to line up first addText box under motif
frame->apanel->NewLine();
frame->addText->item_name = new wxText(frame->apanel, NULL,
(char *)KeyName, "",-1,-1,150,-1);
frame->apanel->NewLine();
frame->addText->brand = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M2Name, "", -1, -1, 150, -1);
frame->apanel->NewLine();
frame->addText->store = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M3Name, "", -1, -1, 150, -1);
frame->apanel->NewLine();
frame->addText->price = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M4Name, "", -1, -1, 75, -1);
frame->apanel->NewLine();
frame->addText->quantity = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M5Name, "", -1, -1, 75, -1);
frame->apanel->NewLine();
add_PurchasingChoice = new wxChoice(frame->apanel, NULL, (char *)M6Name,
-1, -1, -1, -1, 2,
PurchasingChoiceStrings);
add_PurchasingChoice->SetSelection(0);
frame->apanel->NewLine();
frame->apanel->NewLine();
btn_add_add = new wxButton(frame->apanel, (wxFunction)&AddBtnProc, "Add");
btn_add_add->SetClientData((char*)ADD_BUTTON_ADD); // ID the button
btn_add_can = new wxButton(frame->apanel,(wxFunction)&AddBtnProc, "Cancel");
btn_add_can->SetClientData((char*)ADD_BUTTON_CANCEL); // ID the button
btn_add_close = new wxButton(frame->apanel, (wxFunction)&AddBtnProc,
"Close");
btn_add_close->SetClientData((char*)ADD_BUTTON_CLOSE); // ID the button
btn_add_revert = new wxButton(frame->apanel, (wxFunction)&AddBtnProc,
"Revert");
btn_add_revert->SetClientData((char*)ADD_BUTTON_REVERT); // ID the button
// *********************************************************** //
// Object Add Panel Code Ends Here
// *********************************************************** //
// *********************************************************** //
// Object Change Panel Code Starts Here
// *********************************************************** //
frame->changeText = new MyText; // Init MyText Class pointer
CPanelFrame = new wxFrame(NULL, "Changing Object", 0, 0, 400, 400);
// Give it an icon
#ifdef wx_msw
CPanelFrame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
CPanelFrame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
int cpfwidth, cpfheight;
CPanelFrame->GetClientSize(&cpfwidth, &cpfheight);
// Make a panel in the subframe
frame->cpanel = new wxPanel(CPanelFrame, 0, 0,
cpfwidth, cpfheight);
frame->cpanel->SetLabelPosition(wxVERTICAL);
frame->cpanel->SetLabelFont(labelFont);
frame->cpanel->SetButtonFont(itemFont);
frame->cpanel->SetFont(itemFont);
// Needed to line up first panel with the others under motif
frame->cpanel->NewLine();
UString cmesg("Enter the ");
cmesg = cmesg + KeyName + " and click on Search.";
wxMessage *message = new wxMessage(frame->cpanel, cmesg.c_str());
frame->cpanel->NewLine();
frame->changeText->item_name = new wxText(frame->cpanel, NULL,
(char *)KeyName, "",-1,-1,150,-1);
frame->cpanel->NewLine();
frame->changeText->brand = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M2Name, "", -1, -1, 150, -1);
frame->cpanel->NewLine();
frame->changeText->store = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M3Name, "", -1, -1, 150, -1);
frame->cpanel->NewLine();
frame->changeText->price = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M4Name, "", -1, -1, 75, -1);
frame->changeText->quantity = new wxText(frame->cpanel,
(wxFunction)&text_proc,
(char *)M5Name, "",
-1, -1, 75, -1);
frame->cpanel->NewLine();
ch_PurchasingChoice = new wxChoice(frame->cpanel, NULL, (char *)M6Name,
-1, -1, -1, -1, 2,
PurchasingChoiceStrings);
ch_PurchasingChoice->SetSelection(0);
frame->cpanel->NewLine();
frame->changeText->line_total = new wxText(frame->cpanel,
(wxFunction)&text_proc,
(char *)M7Name, "",
-1, -1, 150, -1);
frame->changeText->line_total->SetEditable(FALSE);
frame->cpanel->NewLine();
frame->cpanel->NewLine();
btn_ch_sh = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc, "Search");
btn_ch_sh->SetClientData((char*)CHANGE_BUTTON_SH); // ID the button
btn_ch_cm = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc, "Commit");
btn_ch_cm->SetClientData((char*)CHANGE_BUTTON_CM); // ID the button
btn_ch_cm->Enable(0);
btn_ch_can = new wxButton(frame->cpanel,(wxFunction)&ChBtnProc, "Cancel");
btn_ch_can->SetClientData((char*)CHANGE_BUTTON_CANCEL); // ID the button
btn_ch_close = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc, "Close");
btn_ch_close->SetClientData((char*)CHANGE_BUTTON_CLOSE); // ID the button
btn_ch_revert = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc,
"Revert");
btn_ch_revert->SetClientData((char*)CHANGE_BUTTON_REVERT); // ID the button
// *********************************************************** //
// Object Change Panel Code Ends Here
// *********************************************************** //
// *********************************************************** //
// Object Display Panel Code Starts Here
// *********************************************************** //
frame->displayText = new MyText; // Init MyText Class pointer
DPanelFrame = new wxFrame(NULL, "Displaying Objects", 0, 0,
400, 400);
// Give it an icon
#ifdef wx_msw
DPanelFrame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
DPanelFrame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
int dpfwidth, dpfheight;
DPanelFrame->GetClientSize(&dpfwidth, &dpfheight);
// Make a panel in the subframe
frame->dpanel = new wxPanel(DPanelFrame, 0, 0,
dpfwidth, dpfheight);
frame->dpanel->SetLabelPosition(wxVERTICAL);
frame->dpanel->SetLabelFont(labelFont);
frame->dpanel->SetButtonFont(itemFont);
frame->dpanel->SetFont(itemFont);
// Needed to line up first addText box under motif
frame->dpanel->NewLine();
frame->displayText->item_name = new wxText(frame->dpanel, NULL,
(char *)KeyName, "",-1,-1,150,-1);
frame->displayText->item_name->SetEditable(FALSE);
frame->dpanel->NewLine();
frame->displayText->brand = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M2Name, "", -1, -1, 150, -1);
frame->displayText->brand->SetEditable(FALSE);
frame->dpanel->NewLine();
frame->displayText->store = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M3Name, "", -1, -1, 150, -1);
frame->displayText->store->SetEditable(FALSE);
frame->dpanel->NewLine();
frame->displayText->price = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M4Name, "", -1, -1, 75, -1);
frame->displayText->price->SetEditable(FALSE);
frame->displayText->quantity = new wxText(frame->dpanel,
(wxFunction)&text_proc,
(char *)M5Name, "",
-1, -1, 75, -1);
frame->displayText->quantity->SetEditable(FALSE);
frame->dpanel->NewLine();
frame->displayText->purchasing = new wxText(frame->dpanel,
(wxFunction)&text_proc,
(char *)M6Name, "",
-1, -1, 75, -1);
frame->displayText->purchasing->SetEditable(FALSE);
frame->dpanel->NewLine();
frame->displayText->line_total = new wxText(frame->dpanel,
(wxFunction)&text_proc,
(char *)M7Name, "",
-1, -1, 75, -1);
frame->displayText->line_total->SetEditable(FALSE);
frame->dpanel->NewLine();
frame->dpanel->NewLine();
btn_ds_nx = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Next");
btn_ds_nx->SetClientData((char*)DISPLAY_BUTTON_NX); // ID the button
btn_ds_prev = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Prior");
btn_ds_prev->SetClientData((char*)DISPLAY_BUTTON_PREV); // ID the button
btn_ds_ch = new wxButton(frame->dpanel,(wxFunction)&DsBtnProc, "Change");
btn_ds_ch->SetClientData((char*)DISPLAY_BUTTON_CHANGE); // ID the button
btn_ds_close = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Close");
btn_ds_close->SetClientData((char*)DISPLAY_BUTTON_CLOSE); // ID the button
btn_ds_rm = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Remove");
btn_ds_rm->SetClientData((char*)DISPLAY_BUTTON_REMOVE); // ID the button
// *********************************************************** //
// Object Display Panel Code Ends Here
// *********************************************************** //
// Show the frames
frame->Show(TRUE);
APanelFrame->Show(FALSE);
CPanelFrame->Show(FALSE);
displaying_list = 0;
DPanelFrame->Show(FALSE);
// Vaiable Block Database components
char *FileName = 0;
char *CurrentCfgFile = 0;
char *CfgFile = 0;
Config *CfgData = new Config;
char *AdminUser = 0;
double dfp_val = 0;
const char *DefaultWelcomeMesg = "welcome.txt";
char *WelcomeMesgFile = 0;
#ifdef __USE_MSW_PRINTING__
// Default values for wxWindows MSW Printing
int mswp_lines_per_page = 0;
int mswp_cell_length = 0;
int mswp_font_size = 0;
int mswp_left_margin = 0;
char *mswp_orientation = 0;
char *mswp_doc_name = 0;
char *mswp_font = 0;
#endif // __USE_MSW_PRINTING__
// Look for CfgFile name in environment
if((CurrentCfgFile = getenv(EnvSetting)) == 0)
CfgFile = (char *)DefaultCfgFile;
else
CfgFile = CurrentCfgFile;
// Use default file name if no file is specifed on command line
if(argc < 2) {
int FileStatus = CfgData->Load((char *)CfgFile);
if(!FileStatus) {
Error->Message("Cannot locate any database files!\n",
"Defaulting to: ", DefaultDBFileName);
FileName = (char *)DefaultDBFileName;
WelcomeMesgFile = (char *)DefaultWelcomeMesg;
}
else {
// *********************************************************** //
// Add all startup config file entries here
// *********************************************************** //
FileName = CfgData->GetStrValue("DBFileName");
AdminUser = CfgData->GetStrValue("AdminUser");
WelcomeMesgFile = CfgData->GetStrValue("WelcomeMessageFile");
sales_tax = CfgData->GetDFPValue("SalesTax");
#ifdef __USE_MSW_PRINTING__
// Default values for wxWindows MSW Printing
mswp_lines_per_page = CfgData->GetIntValue("mswpLinesPerPage");
mswp_cell_length = CfgData->GetIntValue("mswpCellLength");
mswp_font_size = CfgData->GetIntValue("mswpFontSize");
mswp_left_margin = CfgData->GetIntValue("mswpLeftMargin");
mswp_orientation = CfgData->GetStrValue("mswpOrientation");
mswp_font = CfgData->GetStrValue("mswpFont");
mswp_doc_name = CfgData->GetStrValue("mswpDocumentName");
#endif // __USE_MSW_PRINTING__
// *********************************************************** //
if(!FileName) {
UString comp("\nDefaulting to: ");
comp = comp + DefaultDBFileName;
Error->Message("DBFileName section missing in config file:\n",
CfgFile, comp.c_str());
FileName = (char *)DefaultDBFileName;
}
}
}
else {
FileName = argv[1];
}
if(!AdminUser) {
AdminRights = 0;
frame->SetStatusText((char *)ProgramName);
}
else {
int result = strcmp(AdminUser, "TRUE");
if(result == 0) {
AdminRights = 1;
frame->SetStatusText("ADMIN USER");
}
else {
AdminRights = 0;
frame->SetStatusText((char *)ProgramName);
}
}
if(!WelcomeMesgFile)
WelcomeMesgFile = (char *)DefaultWelcomeMesg;
#ifdef __USE_MSW_PRINTING__
// Default values for wxWindows MSW Printing
if(mswp_lines_per_page > 0) {
MSWPrintSetup->lines_per_page = mswp_lines_per_page;
MSWPrintSetup->prev_lines_per_page = mswp_lines_per_page;
MSWPrintSetup->default_lines_per_page = mswp_lines_per_page;
}
if(mswp_cell_length > 0) {
MSWPrintSetup->cell_length = mswp_cell_length;
MSWPrintSetup->prev_cell_length = mswp_cell_length;
MSWPrintSetup->default_cell_length = mswp_cell_length;
}
if(mswp_font_size > 0) {
MSWPrintSetup->font_size = mswp_font_size;
MSWPrintSetup->prev_font_size = mswp_font_size;
MSWPrintSetup->default_font_size = mswp_font_size;
}
if(mswp_left_margin > 0) {
MSWPrintSetup->lr_margin = mswp_left_margin;
MSWPrintSetup->prev_lr_margin = mswp_left_margin;
MSWPrintSetup->default_lr_margin = mswp_left_margin;
}
if(mswp_orientation != 0) {
if(strcmp(mswp_orientation, "PORTRAIT") == 0) {
MSWPrintSetup->orientation = 1;
MSWPrintSetup->prev_orientation = 1;
MSWPrintSetup->default_orientation = 1;
}
if(strcmp(mswp_orientation, "LANDSCAPE") == 0) {
MSWPrintSetup->orientation = 0;
MSWPrintSetup->prev_orientation = 0;
MSWPrintSetup->default_orientation = 0;
}
}
if(mswp_font != 0) {
if(strcmp(mswp_font, "SWISS") == 0) {
MSWPrintSetup->font = 0;
MSWPrintSetup->prev_font = 0;
MSWPrintSetup->default_font = 0;
}
if(strcmp(mswp_font, "ROMAN") == 0) {
MSWPrintSetup->font = 1;
MSWPrintSetup->prev_font = 1;
MSWPrintSetup->default_font = 1;
}
if(strcmp(mswp_font, "DECORATIVE") == 0) {
MSWPrintSetup->font = 2;
MSWPrintSetup->prev_font = 2;
MSWPrintSetup->default_font = 2;
}
if(strcmp(mswp_font, "MODERN") == 0) {
MSWPrintSetup->font = 3;
MSWPrintSetup->prev_font = 3;
MSWPrintSetup->default_font = 3;
}
if(strcmp(mswp_font, "SCRIPT") == 0) {
MSWPrintSetup->font = 4;
MSWPrintSetup->prev_font = 4;
MSWPrintSetup->default_font = 4;
}
if(strcmp(mswp_font, "SYSTEM") == 0) {
MSWPrintSetup->font = 5;
MSWPrintSetup->prev_font = 5;
MSWPrintSetup->default_font = 5;
}
}
for(int i = 0; i < mswpDocNameLen; i++) mswpDocumentName[i] = 0;
if(mswp_doc_name != 0)
strcpy(mswpDocumentName, mswp_doc_name);
else
strcpy(mswpDocumentName, ProgramName);
#endif // __USE_MSW_PRINTING__
CfgData->UnLoad(); // Unload the Config file from memory
// Initialize global database pointer
// NOTE: Index file and data file will share the same file name
// with different file extensions. The data file will have a
// .pod extension and the index file will have a .btx extension.
if(AdminRights == 1)
DB = new POD(FileName, RWMode, 1, CacheSize);
else
DB = new POD(FileName, ROMode, 1, CacheSize);
agrocery = new Grocery(DB); // Initialize global buffer pointer
cgrocery = new Grocery(DB); // Initialize global buffer pointer
dgrocery = new Grocery(DB); // Initialize global buffer pointer
// Display the welcome message if it exists
frame->textWin->LoadFile(WelcomeMesgFile);
// Return the main frame window
return frame;
}
MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
wxFrame(frame, title, x, y, w, h)
{
textWin = 0;
apanel = 0;
cpanel = 0;
dpanel = 0;
addText = 0;
changeText = 0;
}
Bool MyFrame::OnClose(void)
// Define the behaviour for the frame closing
{
// Close sub-frames
if(APanelFrame) {
APanelFrame->Close(TRUE);
delete APanelFrame;
}
if(CPanelFrame) {
CPanelFrame->Close(TRUE);
delete CPanelFrame;
}
if(DPanelFrame) {
DPanelFrame->Close(TRUE);
delete DPanelFrame;
}
// Close main frame
Show(FALSE);
// Clean up Variable Block Database objects
if(DB) delete DB;
if(agrocery) delete agrocery;
if(cgrocery) delete cgrocery;
if(dgrocery) delete dgrocery;
return TRUE;
}
void MyFrame::OnMenuCommand(int id)
// Intercept menu commands
{
switch (id) {
case FILE_QUIT:
if (OnClose()) delete this;
break;
case FILE_VBDSTATS:
textWin->Clear();
*(textWin) << "----- Database file statistics -----" << "\n";
VBDStats(textWin, DB->OpenDatabase());
*(textWin) << "----- Index file statistics -----" << "\n";
VBDStats(textWin, DB->OpenIndexFile());
break;
case FILE_EXPORT:
ExportToASCII(*textWin);
break;
case FILE_IMPORT:
ImportFromASCII(*textWin);
break;
case FILE_BACKUP:
BackUp(*textWin);
break;
case FILE_MERGE:
Merge(*textWin);
break;
case FILE_TEMPLATE:
CreateTemplate(*textWin);
break;
case FILE_COMPARE_INDEX:
CompareIndexFile(*textWin);
break;
case FILE_REBUILD_INDEX:
RebuildIndexFile(*textWin);
break;
case EDIT_CUT:
textWin->Cut();
break;
case EDIT_COPY:
textWin->Copy();
break;
case EDIT_PASTE:
textWin->Paste();
break;
case DB_ADD:
Add(*textWin);
break;
case DB_CHANGE:
Change(*textWin);
break;
case DB_REMOVE:
Remove(*textWin);
break;
case DB_DISPLAY_PURCHASING:
display_all = 0;
DisplayDB(*textWin);
break;
case DB_DISPLAY_ALL:
display_all = 1;
DisplayDB(*textWin);
break;
case DB_RESET_PURCHASING:
SetPurchasing(*textWin, 'N');
break;
case DB_SET_ALL_PURCHASING:
SetPurchasing(*textWin, 'Y');
break;
case FIND_BYNAME:
FindBy(*textWin, KeyName, NAME);
break;
case FIND_BYBRAND:
FindBy(*textWin, M2Name, BRAND);
break;
case FIND_BYSTORE:
FindBy(*textWin, M3Name, STORE);
break;
#ifdef __USE_MSW_PRINTING__
case WXPRINT_PRINT_PURCHASING:
{
print_all = 0;
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
wxPrinter printer(&printData);
if(displaying_list) {
int yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxYES) print_list = 1; else print_list = 0;
}
else
print_list = 0;
wGrocPrint printout((char *)ProgramName);
if (!printer.Print(this, &printout, TRUE))
wxMessageBox("The document was not printed.",
"Printing", wxOK);
break;
}
case WXPRINT_PRINT_ALL:
{
print_all = 1;
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
wxPrinter printer(&printData);
if(displaying_list) {
int yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxYES) print_list = 1; else print_list = 0;
}
else
print_list = 0;
wGrocPrint printout((char *)ProgramName);
if (!printer.Print(this, &printout, TRUE))
wxMessageBox("The document was not printed.",
"Printing", wxOK);
break;
}
case WXPRINT_PREVIEW_ALL:
{
print_all = 1;
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
if(displaying_list) {
int yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxYES) print_list = 1; else print_list = 0;
}
else
print_list = 0;
// Pass two printout objects: for preview, and possible printing.
wxPrintPreview *preview = \
new wxPrintPreview(new wGrocPrint((char *)ProgramName),
new wGrocPrint((char *)ProgramName),
&printData);
if (!preview->Ok()) {
delete preview;
wxMessageBox("There was a problem previewing.",
"Previewing", wxOK);
return;
}
wxPreviewFrame *frame = new wxPreviewFrame(preview,
this,
(char *)ProgramName,
100, 100, 600, 650);
frame->Centre(wxBOTH);
frame->Initialize();
frame->Show(TRUE);
break;
}
case WXPRINT_PREVIEW_PURCHASING :
{
print_all = 0;
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
if(displaying_list) {
int yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxYES) print_list = 1; else print_list = 0;
}
else
print_list = 0;
// Pass two printout objects: for preview, and possible printing.
wxPrintPreview *preview = \
new wxPrintPreview(new wGrocPrint((char *)ProgramName),
new wGrocPrint((char *)ProgramName),
&printData);
if (!preview->Ok()) {
delete preview;
wxMessageBox("There was a problem previewing.",
"Previewing", wxOK);
return;
}
wxPreviewFrame *frame = new wxPreviewFrame(preview,
this,
(char *)ProgramName,
100, 100, 600, 650);
frame->Centre(wxBOTH);
frame->Initialize();
frame->Show(TRUE);
break;
}
case WXPRINT_PRINTER_SETUP:
{
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
wxPrintDialog printerDialog(this, &printData);
printerDialog.GetPrintData().SetSetupDialog(TRUE);
printerDialog.Show(TRUE);
break;
}
case WXPRINT_PAGE_SETUP:
{
int xpos=300; int ypos=300; int width=300;
#ifdef wx_msw
int height=250;
#else
// Allow MSW style printing under UNIX
int height=350;
#endif
wxPageDialog = new wxDialogBox(this, "Page Setup", TRUE,
xpos, ypos, width, height,
wxDEFAULT_DIALOG_STYLE,
"Page Setup");
wxPageDialog->Centre();
wxPageDialog->NewLine();
LppSlider = new wxSlider(wxPageDialog, NULL, "Lines Per Page",
MSWPrintSetup->lines_per_page,
1, 200, 200);
wxPageDialog->NewLine();
CellSlider = new wxSlider(wxPageDialog, NULL, "Cell Length",
MSWPrintSetup->cell_length,
1, 50, 150);
wxPageDialog->NewLine();
FsSlider = new wxSlider(wxPageDialog, NULL, "Font Size ",
MSWPrintSetup->font_size,
1, 50, 150);
wxPageDialog->NewLine();
LRMSlider = new wxSlider(wxPageDialog, NULL, "Left Margin",
MSWPrintSetup->lr_margin,
1, 20, 150);
wxPageDialog->NewLine();
wxMessage *om = new wxMessage(wxPageDialog,
"The Orientation must match the Printer Setup");
wxPageDialog->NewLine();
OrientationChoice = new wxChoice(wxPageDialog, NULL, "Orientation",
-1, -1, -1, -1, 2, OrChoiceStrings);
OrientationChoice->SetSelection(MSWPrintSetup->orientation);
wxPageDialog->NewLine();
FontChoice = new wxChoice(wxPageDialog, NULL, "Font",
-1, -1, -1, -1, 6, FontChoiceStrings);
FontChoice->SetSelection(MSWPrintSetup->font);
wxPageDialog->NewLine();
btn_pdb_close = new wxButton(wxPageDialog, (wxFunction)&page_btn_proc,
"Close", 10, -1, -1, -1);
btn_pdb_close->SetClientData((char*)PAGE_DIALOG_BUTTON_CLOSE);
btn_pdb_accept = new wxButton(wxPageDialog, (wxFunction)&page_btn_proc,
"Accept", 60, -1, -1, -1);
btn_pdb_accept->SetClientData((char*)PAGE_DIALOG_BUTTON_ACCEPT);
btn_pdb_cancel = new wxButton(wxPageDialog, (wxFunction)&page_btn_proc,
"Cancel", 118, -1, -1, -1);
btn_pdb_cancel->SetClientData((char*)PAGE_DIALOG_BUTTON_CANCEL);
btn_pdb_default = new wxButton(wxPageDialog,
(wxFunction)&page_btn_proc,
"Default", 175, -1, -1, -1);
btn_pdb_default->SetClientData((char*)PAGE_DIALOG_BUTTON_DEFAULT);
wxPageDialog->Show(TRUE);
break;
}
#endif // __USE_MSW_PRINTING__
case PRINT_POSTSCRIPT_PURCHASING:
ps_print_all = 0;
PostScriptPrint(*textWin);
break;
case PRINT_POSTSCRIPT_ALL:
ps_print_all = 1;
PostScriptPrint(*textWin);
break;
case PRINT_ASCII_PURCHASING:
as_print_all = 0;
ASCIIPrintAll(*textWin);
break;
case PRINT_ASCII_ALL:
as_print_all = 1;
ASCIIPrintAll(*textWin);
break;
case VIEW_CLEAR:
Clear(*textWin);
break;
case VIEW_TOTAL_PURCHASING :
view_all = 0;
ViewTotals(*textWin);
break;
case VIEW_TOTAL_ALL :
view_all = 1;
ViewTotals(*textWin);
break;
case HELP_ABOUT: {
char *s = VerNumber();
UString mesg(ProgramName);
mesg = mesg + "\nVersion Number " + s;
wxMessageBox(mesg.c_str(), "About", wxOK|wxCENTRE);
break;
}
case HELP_USERLEVEL: {
UString mesg;
if(AdminRights) {
mesg = mesg + "You have Admin User Privileges\n" + \
"As defined in the " + DefaultCfgFile + " config file\n";
wxMessageBox(mesg.c_str(), "Access Level", wxOK|wxCENTRE);
}
else {
mesg = mesg + "You do not have Admin User Privileges\n" + \
"As defined in the " + DefaultCfgFile + " config file\n";
wxMessageBox(mesg.c_str(), "Access Level", wxOK|wxCENTRE);
}
break;
}
}
}
void MyTextWindow::OnChar(wxKeyEvent& event)
{
if(event.keyCode == CONTROL('x')) {
Cut();
frame->SetStatusText("Cut text and copied to clipboard");
}
if(event.keyCode == CONTROL('c')) {
Copy();
frame->SetStatusText("Copied text from clipboard");
}
if(event.keyCode == CONTROL('v')) {
Paste();
frame->SetStatusText("Pasted text from clipboard");
}
wxTextWindow::OnChar(event); // Process the default behavior
}
void MyFrame::OnSize(int w, int h)
{
wxFrame::OnSize(w, h);
}
MyText::MyText(wxPanel *parent, wxFunction func, char *label,
char *value, int x, int y, int width, int height ,
long style, char *name) :
wxText(parent, func, label, value,x, y, width, height , style, name)
{
item_name = brand = store = price = quantity = purchasing = line_total = 0;
}
MyText::~MyText()
{
if(item_name) delete item_name;
if(brand) delete brand;
if(store) delete store;
if(price) delete price;
if(quantity) delete quantity;
if(purchasing) delete purchasing;
if(line_total) delete line_total;
}
void Clear(MyTextWindow& textWin)
{
textWin.Clear();
}
char *VerNumber()
// Version number for this windows program. Edit the version.h
// file to change this program's version number
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%.3f", VersionNumber);
int len = strlen(sbuffer);
char *s = new char[len+1];
s[len+1] = '\0';
strcpy(s, sbuffer);
return s;
}
void text_proc(wxText &but, wxCommandEvent &event)
{
// Nothing to do
}
void AddBtnProc(wxButton& but, wxCommandEvent& event)
{
UString sbuf; // Character string input buffer
long tag = (long)but.GetClientData() ;
double price;
long quantity;
int i, rv;
char purchasing;
char sbuffer[sbuffer_len];
FLOAT64 line_total;
if(tag == ADD_BUTTON_ADD) {
UString item_name;
UString brand;
UString store;
item_name = frame->addText->item_name->GetValue();
brand = frame->addText->brand->GetValue();
store = frame->addText->store->GetValue();
price = atof(frame->addText->price->GetValue());
quantity = atoi(frame->addText->quantity->GetValue());
rv = add_PurchasingChoice->GetSelection();
// Remove any leading space from the key name entry
int offset = item_name.Find(" ");
if(offset == 0) item_name.DeleteAt(offset, 1);
if(item_name == "") { // Check for a key name valid input
sbuf = sbuf + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
return;
}
Grocery grocery(DB);
grocery.SetName(item_name);
FAU addr = grocery.FindObject();
if(addr) {
sbuf = sbuf + "An Entry for " + item_name + " already exists!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
return;
}
agrocery->SetName(item_name.c_str());
agrocery->SetBrand(brand.c_str());
agrocery->SetStore(store.c_str());
agrocery->SetPrice(price);
agrocery->SetQuantity(quantity);
if(rv == 0)
agrocery->SetPurchasing('N');
else
agrocery->SetPurchasing('Y');
line_total = agrocery->GetPrice() * agrocery->GetQuantity();
agrocery->SetLineTotal(line_total);
addr = agrocery->AddObject(0); // Write the object to the file
if(!addr) {
sbuf = sbuf + "Could not add Entry for " + agrocery->GetName();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
return;
}
sbuf = sbuf + "Added Entry for " + agrocery->GetName();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
ClearAddPanel();
if(displaying_list) {
InMemCopy inmemcopy(agrocery->GetName(), agrocery->ObjectAddress(),
agrocery->GetClassID());
dllist->StoreNode(inmemcopy);
}
}
if(tag == ADD_BUTTON_CANCEL) {
ClearAddPanel();
return;
}
if(tag == ADD_BUTTON_CLOSE) {
APanelFrame->Show(FALSE);
return;
}
if(tag == ADD_BUTTON_REVERT) {
if(agrocery->GetName())
frame->addText->item_name->SetValue(agrocery->GetName());
if(agrocery->GetBrand())
frame->addText->brand->SetValue(agrocery->GetBrand());
if(agrocery->GetStore())
frame->addText->store->SetValue(agrocery->GetStore());
price = agrocery->GetPrice();
sprintf(sbuffer, "%.2f", price);
frame->addText->price->SetValue(sbuffer);
quantity = agrocery->GetQuantity();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%d", quantity);
frame->addText->quantity->SetValue(sbuffer);
purchasing = agrocery->GetPurchasing();
if(purchasing == 'N' || purchasing == 'n')
add_PurchasingChoice->SetSelection(0);
else
add_PurchasingChoice->SetSelection(1);
return;
}
}
void ClearAddPanel()
{
frame->addText->item_name->SetValue("");
frame->addText->brand->SetValue("");
frame->addText->store->SetValue("");
frame->addText->price->SetValue("");
frame->addText->quantity->SetValue("");
add_PurchasingChoice->SetSelection(0);
}
void Add(MyTextWindow &textWin)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
textWin.Clear();
textWin << "Adding objects to database..." << "\n";
textWin << "\n";
APanelFrame->Show(TRUE); // Show the Add Panel Frame
}
void ChBtnProc(wxButton& but, wxCommandEvent& event)
{
UString sbuf, item_name; // Character input string buffer
long tag = (long)but.GetClientData() ;
double price, line_total;
long quantity;
int i, rv, offset;
char purchasing;
char sbuffer[sbuffer_len];
if(tag == CHANGE_BUTTON_SH) {
item_name = frame->changeText->item_name->GetValue();
// Remove any leading space from the key name entry
offset = item_name.Find(" ");
if(offset == 0) item_name.DeleteAt(offset, 1);
if(item_name == "") { // Check for a key name valid input
sbuf = sbuf + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
btn_ch_cm->Enable(0);
return;
}
Grocery grocery(DB);
grocery.SetName(item_name);
FAU addr = grocery.FindObject();
if(!addr) {
sbuf = sbuf + "Could not find an entry for " + item_name;
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
btn_ch_cm->Enable(0);
return;
}
cgrocery->Copy(grocery);
if(cgrocery->GetBrand())
frame->changeText->brand->SetValue(cgrocery->GetBrand());
if(cgrocery->GetStore())
frame->changeText->store->SetValue(cgrocery->GetStore());
price = cgrocery->GetPrice();
sprintf(sbuffer, "%.2f", price);
frame->changeText->price->SetValue(sbuffer);
quantity = cgrocery->GetQuantity();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%d", quantity);
frame->changeText->quantity->SetValue(sbuffer);
purchasing = cgrocery->GetPurchasing();
if(purchasing == 'N' || purchasing == 'n')
ch_PurchasingChoice->SetSelection(0);
else
ch_PurchasingChoice->SetSelection(1);
line_total = cgrocery->GetLineTotal();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%.2f", line_total);
frame->changeText->line_total->SetValue(sbuffer);
frame->changeText->line_total->SetEditable(FALSE);
btn_ch_cm->Enable(1); // Enable the commit button
}
if(tag == CHANGE_BUTTON_CM) {
item_name = frame->changeText->item_name->GetValue();
// Remove any leading space from the key name entry
offset = item_name.Find(" ");
if(offset == 0) item_name.DeleteAt(offset, 1);
if(item_name == "") { // Check for a key name valid input
sbuf = sbuf + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
btn_ch_cm->Enable(0);
return;
}
Grocery changed(DB); // Buffer used to store changes
changed.SetName(frame->changeText->item_name->GetValue());
changed.SetBrand(frame->changeText->brand->GetValue());
changed.SetStore(frame->changeText->store->GetValue());
price = atof(frame->changeText->price->GetValue());
changed.SetPrice(price);
quantity = atoi(frame->changeText->quantity->GetValue());
changed.SetQuantity(quantity);
rv = ch_PurchasingChoice->GetSelection();
if(rv == 0)
changed.SetPurchasing('N');
else
changed.SetPurchasing('Y');
FLOAT64 ltotal = changed.GetPrice() * changed.GetQuantity();
changed.SetLineTotal(ltotal);
// Disable the commit button after changing the object
btn_ch_cm->Enable(0);
if(changed.FullCompare(*cgrocery)) { // The object has not changed
sbuf = sbuf + "No changes to commit for " + cgrocery->GetName();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
ClearChangePanel();
if(displaying_list) { //Objects are being displayed
if(!dllist->IsEmpty()) DPanelFrame->Show(TRUE);
}
btn_ch_cm->Enable(0);
return;
}
UString key_name(changed.GetName());
UString old_key_name(cgrocery->GetName());
// If the key name is changed, ensure no duplicates are added
if(key_name != old_key_name) {
if((__LWORD__)changed.FindObject()) {
sbuf = sbuf + "An Entry for " + key_name + " already exists!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
if(displaying_list) { // Objects are being displayed
if(!dllist->IsEmpty()) DPanelFrame->Show(TRUE);
}
btn_ch_cm->Enable(0);
return;
}
}
FAU oa = cgrocery->ObjectAddress(); // Record address before deleting
cgrocery->DeleteObject(); // Remove the object
changed.AddObject(0); // Add the changed object back to the database
sbuf = sbuf + "Commited changes for " + changed.GetName();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
ClearChangePanel();
// Update any list entries for display panel
if(displaying_list) { // Objects are being displayed
if(dllist->IsEmpty()) {
displaying_list = 0;
DPanelFrame->Show(FALSE);
return;
}
InMemCopy inmemcopy(cgrocery->GetName(), oa, cgrocery->GetClassID());
DNode<InMemCopy> *prevptr = dllistptr;
dllistptr = (DNode<InMemCopy> *)dllist->Find(inmemcopy);
if(dllistptr) {
dllistptr->Data.key = changed.GetName();
dllistptr->Data.object_address = changed.ObjectAddress();
dllistptr->Data.class_id = changed.GetClassID();
if(displaying_list) {
DPanelFrame->Show(TRUE);
DisplayObject(changed);
}
}
else {
dllistptr = prevptr;
dllistptr->Data.key = changed.GetName();
dllistptr->Data.object_address = changed.ObjectAddress();
dllistptr->Data.class_id = changed.GetClassID();
if(displaying_list) {
DPanelFrame->Show(TRUE);
DisplayObject(changed);
}
}
}
}
if(tag == CHANGE_BUTTON_CANCEL) {
ClearChangePanel();
if(displaying_list) { // Objects are being displayed
if(!dllist->IsEmpty()) DPanelFrame->Show(TRUE);
}
btn_ch_cm->Enable(0);
return;
}
if(tag == CHANGE_BUTTON_CLOSE) {
ClearChangePanel();
CPanelFrame->Show(FALSE);
btn_ch_cm->Enable(0);
return;
}
if(tag == CHANGE_BUTTON_REVERT) {
if(cgrocery->GetName())
frame->changeText->item_name->SetValue(cgrocery->GetName());
if(cgrocery->GetBrand())
frame->changeText->brand->SetValue(cgrocery->GetBrand());
if(cgrocery->GetStore())
frame->changeText->store->SetValue(cgrocery->GetStore());
price = cgrocery->GetPrice();
sprintf(sbuffer, "%.2f", price);
frame->changeText->price->SetValue(sbuffer);
quantity = cgrocery->GetQuantity();
for(int i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%d", quantity);
frame->changeText->quantity->SetValue(sbuffer);
purchasing = cgrocery->GetPurchasing();
if(purchasing == 'N' || purchasing == 'n')
ch_PurchasingChoice->SetSelection(0);
else
ch_PurchasingChoice->SetSelection(1);
line_total = cgrocery->GetPrice() * cgrocery->GetQuantity();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%.2f", line_total);
frame->changeText->line_total->SetValue(sbuffer);
btn_ch_cm->Enable(0);
return;
}
}
void ClearChangePanel()
{
frame->changeText->item_name->SetValue("");
frame->changeText->brand->SetValue("");
frame->changeText->store->SetValue("");
frame->changeText->price->SetValue("");
frame->changeText->quantity->SetValue("");
ch_PurchasingChoice->SetSelection(0);
frame->changeText->line_total->SetValue("");
}
void Change(MyTextWindow &textWin)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
textWin.Clear();
textWin << "Changing objects in database..." << "\n";
textWin << "\n";
CPanelFrame->Show(TRUE); // Show the Add Panel Frame
}
void Remove(MyTextWindow &textWin, char *keyNM)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
textWin.Clear();
textWin << "Removing object from database..." << "\n";
UString item_name;
UString comp;
char *buf;
if(!keyNM) {
comp = comp + "Enter " + KeyName + " to Remove:";
buf = wxGetTextFromUser(comp.c_str(), "String Input");
if(!buf) {
textWin << "Canceled." << "\n";
return;
}
item_name = buf;
// Remove any leading space from the key name entry
int offset = item_name.Find(" ");
if(offset == 0) item_name.DeleteAt(offset, 1);
if(item_name == "") { // Check for a key name valid input
comp.DeleteAt(0, comp.length());
comp = comp + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(comp.c_str());
frame->textWin->WriteText("\n");
Error->Message(comp.c_str());
return;
}
}
else
item_name = keyNM; // Key name memeber
Grocery grocery(DB);
grocery.SetName(item_name);
FAU addr = grocery.FindObject();
if(!addr) {
comp.DeleteAt(0, comp.length());
comp = comp + "Could not find an entry for: " + item_name.c_str();
Error->Message(comp.c_str());
textWin << comp.c_str() << "\n";
return;
}
int yn = wxMessageBox("Are you sure you want to remove",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxNO) return;
InMemCopy listdata(grocery.GetName(), grocery.ObjectAddress(),
grocery.GetClassID());
grocery.DeleteObject();
textWin << "Removed entry for: " << item_name.c_str() << "\n";
// Update display item panel list
if(displaying_list) {
if(dllist->IsEmpty()) {
displaying_list = 0;
DPanelFrame->Show(TRUE);
return;
}
DNode<InMemCopy> *dllptr = 0;
dllptr = (DNode<InMemCopy> *)dllist->Find(listdata);
if(dllptr) {
dllist->Delete(dllptr);
wxCommandEvent wxevent1(wxEVENT_TYPE_BUTTON_COMMAND);
DsBtnProc(*btn_ds_nx, wxevent1); // Simulate pushing the Next Button
}
}
}
void DsBtnProc(wxButton& but, wxCommandEvent& event)
{
char *sbuf = 0; // Character string buffer
long tag = (long)but.GetClientData() ;
Grocery grocery(DB);
if(tag == DISPLAY_BUTTON_NX) {
if(!dllistptr) return;
if(!dllist) return;
if(dllist->IsEmpty()) {
ClearDisplayPanel();
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
else
dllistptr = dllistptr->GetNext();
if(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
DisplayObject(grocery);
}
else {
wxMessageBox("Reached the end of the list\n",
"Program Message", wxOK|wxCENTRE);
dllistptr = dllist->GetFront();
grocery.ReadObject(dllistptr->Data.object_address);
DisplayObject(grocery);
}
}
if(tag == DISPLAY_BUTTON_PREV) {
if(!dllistptr) return;
if(!dllist) return;
if(dllist->IsEmpty()) {
ClearDisplayPanel();
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
else
dllistptr = dllistptr->GetPrior();
if(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
DisplayObject(grocery);
}
else {
wxMessageBox("Reached the beginning of the list\n",
"Program Message", wxOK|wxCENTRE);
dllistptr = dllist->GetBack();
grocery.ReadObject(dllistptr->Data.object_address);
DisplayObject(grocery);
}
}
if(tag == DISPLAY_BUTTON_CHANGE) {
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
if(dllist->IsEmpty()) {
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
if(!dllist->IsEmpty()) {
grocery.ReadObject(dllistptr->Data.object_address);
cgrocery->Copy(grocery);
}
else
cgrocery->Copy(*dgrocery);
frame->changeText->item_name->SetValue(cgrocery->GetName());
wxCommandEvent wxevent(wxEVENT_TYPE_BUTTON_COMMAND);
ChBtnProc(*btn_ch_sh, wxevent); // Simulate pushing the Search Button
CPanelFrame->Show(TRUE); // Show the Change Panel Frame
}
if(tag == DISPLAY_BUTTON_CLOSE) {
ClearDisplayPanel();
displaying_list = 0;
DPanelFrame->Show(FALSE);
CPanelFrame->Show(FALSE);
if(!dllist->IsEmpty()) dllist->Clear();
return;
}
if(tag == DISPLAY_BUTTON_REMOVE) {
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
if(dllist->IsEmpty()) {
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
else
Remove(*frame->textWin, dgrocery->GetName());
}
}
void ClearDisplayPanel()
{
frame->displayText->item_name->SetValue("");
frame->displayText->brand->SetValue("");
frame->displayText->store->SetValue("");
frame->displayText->price->SetValue("");
frame->displayText->quantity->SetValue("");
frame->displayText->purchasing->SetValue("");
frame->displayText->line_total->SetValue("");
}
void DisplayObject(Grocery &grocery)
{
dgrocery->Copy(grocery); // Initialize global display object
double price, line_total;
long quantity;
int i;
char purchasing;
char sbuffer[sbuffer_len];
if(grocery.GetName())
frame->displayText->item_name->SetValue(grocery.GetName());
if(grocery.GetBrand())
frame->displayText->brand->SetValue(grocery.GetBrand());
if(grocery.GetStore())
frame->displayText->store->SetValue(grocery.GetStore());
price = grocery.GetPrice();
sprintf(sbuffer, "%.2f", price);
frame->displayText->price->SetValue(sbuffer);
quantity = grocery.GetQuantity();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%d", quantity);
frame->displayText->quantity->SetValue(sbuffer);
purchasing = grocery.GetPurchasing();
if(purchasing == 'N' || purchasing == 'n')
frame->displayText->purchasing->SetValue("No");
else
frame->displayText->purchasing->SetValue("Yes");
line_total = grocery.GetLineTotal();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%.2f", line_total);
frame->displayText->line_total->SetValue(sbuffer);
displaying_list = 1;
DPanelFrame->Show(TRUE);
}
void LoadGKeys(EntryKey &e)
// Visit function used to load the btree keys into memory
{
Grocery grocery(DB);
char purchasing;
grocery.ReadObject(e.object_address);
if(purchase_all) {
InMemCopy inmemcopy(e.key, e.object_address, e.class_id);
dllist->StoreNode(inmemcopy);
grand_total += grocery.GetLineTotal();
num_objects++;
}
else {
purchasing = grocery.GetPurchasing();
if(purchasing == 'Y' || purchasing == 'y') {
InMemCopy inmemcopy(e.key, e.object_address, e.class_id);
dllist->StoreNode(inmemcopy);
grand_total += grocery.GetLineTotal();
num_objects++;
}
}
}
int LoadIndexKeys(int load_all)
{
grand_total = 0;
num_objects = 0;
purchase_all = load_all;
dllist->Clear();
BtreeWalker btw(DB->Index());
btw.Sort(LoadGKeys);
if(num_objects > 0) print_list = 1;
return num_objects;
}
void ReOrderDisplayList()
{
if(dllist->IsEmpty()) return;
Grocery grocery(DB);
char purchasing;
dllistptr = dllist->GetFront();
DLList<InMemCopy> tmp_list;
grand_total = 0;
num_objects = 0;
while(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
purchasing = grocery.GetPurchasing();
if(purchasing == 'Y' || purchasing == 'y') {
grand_total += grocery.GetLineTotal();
num_objects++;
tmp_list.StoreNode(dllistptr->Data);
}
dllistptr = dllistptr->GetNext();
}
dllist->Copy(tmp_list);
// Always close the display panel after reordering the list
if(displaying_list == 1) {
displaying_list = 0;
DPanelFrame->Show(FALSE);
}
}
void DisplayDB(MyTextWindow &textWin)
{
Grocery grocery(DB);
char purchasing;
textWin.Clear();
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "Displaying the database objects." << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
num_objects = LoadIndexKeys(display_all);
if(display_all == 0) {
textWin << "Displaying objects select for purchase only." << "\n";
if(num_objects == 0) {
textWin << "Nothing to display." << "\n";
return;
}
textWin << "Displaying " << num_objects << " objects..." << "\n";
}
else {
textWin << "Displaying all objects in the database." << "\n";
if(num_objects == 0) {
textWin << "Nothing to display." << "\n";
return;
}
textWin << "Displaying " << num_objects << " objects..." << "\n";
}
dllistptr = dllist->GetFront();
// Display the first object
grocery.ReadObject(dllistptr->Data.object_address);
if(display_all == 0) {
purchasing = grocery.GetPurchasing();
if(purchasing == 'N' || purchasing == 'n') return;
}
DisplayObject(grocery);
}
void FindBy(MyTextWindow &textWin, const char *MemberName, GrocDBItem item)
{
textWin.Clear();
textWin << "Searching for object by " << (char *)MemberName << "\n";
UString comp;
comp = comp + "Enter complete string or use " + WildCard + \
" for a wild card:";
char *buf = wxGetTextFromUser(comp.c_str(), (char *)MemberName);
if(!buf) {
textWin << "Canceled." << "\n";
return;
}
UString name(buf);
// Remove any leading space from the key name entry
unsigned offset = name.Find(" ");
if(offset == 0) name.DeleteAt(offset, 1);
if(name == "") { // Check for a key name valid input
comp.DeleteAt(0, comp.length());
comp = comp + "Invalid " + MemberName + " input!";
frame->textWin->WriteText(comp.c_str());
frame->textWin->WriteText("\n");
Error->Message(comp.c_str());
return;
}
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
Grocery grocery(DB);
offset = name.Find(WildCard); // Look for wild card character
if(offset == UString::NoMatch) { // No wild cards found
grocery.SetName(buf);
GrocDBSearch(grocery, item, name, textWin);
return;
}
else
GrocDBSearch(grocery, item, name, textWin, WildCard);
}
void GrocDBSearch(Grocery &grocery, GrocDBItem item, UString &str,
MyTextWindow &textWin, const char *wildcard)
{
textWin << "Searching for " << str.c_str() << "\n";
int offset;
offset = ObjectsFound = 0;
if(wildcard != 0) {
while(1) { // Remove the wild card characters from the string
offset = str.Find(wildcard, offset);
if (offset == UString::NoMatch) break;
str.DeleteAt(offset, strlen(wildcard));
offset++;
}
}
// Ensure that the memory buffers and the file data
// stay in sync during multiple file access.
DB->Index()->TestTree();
dllist->Clear();
if(wildcard != 0)
BtreeSearch(DB->Index(), item, grocery, str, 1);
else
BtreeSearch(DB->Index(), item, grocery, str);
if(ObjectsFound == 0) {
textWin << "No matches found." << "\n";
return;
}
else
num_objects = ObjectsFound;
dllistptr = dllist->GetFront();
grand_total = 0;
while(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
grand_total += grocery.GetLineTotal();
dllistptr = dllistptr->GetNext();
}
UString comp;
int yn;
if(ObjectsFound > 1) { // Found multiple matches
textWin << "Found " << ObjectsFound << " matching." << "\n";
char intbuf[sbuffer_len];
sprintf(intbuf, "%d", ObjectsFound);
comp = comp + "Found " + intbuf + " matching.\nDisplay the objects?";
yn = wxMessageBox(comp.c_str(), "Program Message", wxYES_NO|wxCENTRE);
}
else {
textWin << "Found matching entry for: " << str.c_str() << "\n";
comp = comp + "Found matching entry for: " + str + \
"\nDisplay the object?";
yn = wxMessageBox(comp.c_str(), "Program Message", wxYES_NO|wxCENTRE);
}
if(yn == wxNO) {
dllist->Clear();
return;
}
// Display the first object
dllistptr = dllist->GetFront();
grocery.ReadObject(dllistptr->Data.object_address);
DisplayObject(grocery);
}
void ExportToASCII(MyTextWindow &textWin)
{
const char dchar = '\t'; // Text delimiter
const char filter = '\t'; // Filter out tabs
const char *Fill = "None"; // Fill character string
double price, line_total;
char purchasing;
long quantity;
int yn, i;
char sbuffer[sbuffer_len];
Grocery grocery(DB);
textWin.Clear();
textWin << "Exporting database to ASCII file delimited by tabs..." << "\n";
if(DB->RebuildIndex()) {
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
if(displaying_list) {
yn = wxMessageBox("Export display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
}
else
yn = wxNO;
if(yn == wxNO) { LoadIndexKeys(); }
if(dllist->IsEmpty()) { LoadIndexKeys(); }
char *FileName = wxFileSelector("Export to file:", NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Export canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists! Overwrite it?";
yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Export canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Exporting database to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
// Write the item bar to the file first
ASPrint(KeyName, stream, strlen(KeyName));
stream << dchar;
ASPrint(M2Name, stream, strlen(M2Name));
stream << dchar;
ASPrint(M3Name, stream, strlen(M3Name));
stream << dchar;
ASPrint(M4Name, stream, strlen(M4Name));
stream << dchar;
ASPrint(M5Name, stream, strlen(M5Name));
stream << dchar;
ASPrint(M6Name, stream, strlen(M6Name));
stream << dchar;
ASPrint(M7Name, stream, strlen(M7Name));
stream << asLineFeed;
int exports = 0;
dllistptr = dllist->GetFront();
while(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
ASPrint(grocery.GetName(), filter, stream, strlen(grocery.GetName()));
stream << dchar;
if(!*grocery.GetBrand())
ASPrint(Fill, stream, strlen(Fill));
else
ASPrint(grocery.GetBrand(), filter, stream, strlen(grocery.GetBrand()));
stream << dchar;
if(!*grocery.GetStore())
ASPrint(Fill, stream, strlen(Fill));
else
ASPrint(grocery.GetStore(), filter, stream, strlen(grocery.GetStore()));
stream << dchar;
price = grocery.GetPrice();
sprintf(sbuffer, "%.2f", price);
ASPrint(sbuffer, stream, strlen(sbuffer));
stream << dchar;
quantity = grocery.GetQuantity();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%d", quantity);
ASPrint(sbuffer, stream, strlen(sbuffer));
stream << dchar;
purchasing = grocery.GetPurchasing();
if(purchasing == 'N' || purchasing == 'n')
ASPrint("No", stream, strlen("No"));
else
ASPrint("Yes", stream, strlen("Yes"));
stream << dchar;
line_total = grocery.GetLineTotal();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%.2f", line_total);
ASPrint(sbuffer, stream, strlen(sbuffer));
stream << asLineFeed;
exports++;
dllistptr = dllistptr->GetNext();
}
textWin << "Exported " << exports << " objects." << "\n";
stream.close();
}
void ImportFromASCII(MyTextWindow &textWin)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
char words[MAXWORDS][MAXWORDLENGTH];
int num;
const int MaxLine = 512;
char LineBuffer[MaxLine];
UString sbuf;
const char dchar = '\t'; // Text delimiter
// wxWindows single choice index box setup
int ch = -1;
const int CHArray = 4;
char *ch_array[CHArray] = {
"Update this entry",
"Skip this entry",
"Update all entries without prompting",
"Quit this import"
};
enum ICHOICES {
UPDATE_ENTRY,
UPDATE_SKIP,
UPDATE_ALL,
QUIT_THIS
};
textWin.Clear();
textWin << "Importing database from ASCII file delimited by tabs..." << "\n";
char *FileName = wxFileSelector("Import from file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Import canceled." << "\n";
return; // No vaild file name
}
ifstream stream(FileName, ios::in|ios::nocreate);
textWin << "Importing database from: " << FileName << "\n";
if(!stream) { // Could not open the stream
textWin << "Could not open file: " << FileName << "\n";
return;
}
textWin << "Importing..." << "\n";
SNode<UString> *sllistptr; // Linked list node pointer
SLList<UString> sllist; // Linked list
while(!stream.eof())
{
// Read in file line by line
stream.getline(LineBuffer, MaxLine);
// Copy contents of the array to temporary holding buffer
sbuf = LineBuffer;
// Load file data into singly-linked list
sllistptr = sllist.StoreNode(sbuf);
// Clear the string buffer
sbuf.DeleteAt(0, sbuf.length());
if(!sllistptr) { // Out of memory
stream.close();
sllist.Clear();
return;
}
}
stream.close();
Grocery grocery(DB);
Grocery grocery_a(DB);
Grocery ob(DB);
int linecount = 0;
int imports = 0;
int updates = 0;
int updateall = 0;
int ObjectItems = 7; // Number of class data members
sllistptr = sllist.GetFront();
while(!sllist.IsHeader(sllistptr)) {
if(parse(sllistptr->Data.c_str(), words, &num, dchar) == 1) {
textWin << "Parse error!" << "\n";
break;
}
linecount++;
if(num != ObjectItems && (num != 0 && num != 1)) {
textWin << "Error in " << FileName << " import file!" << "\n";
if(num > ObjectItems)
textWin << "To many items on line: ";
if(num < ObjectItems)
textWin << "Not enough items on line: ";
textWin << linecount << "\n";
int yn = wxMessageBox("Error in import file! Continue?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
sllist.Clear();
return;
}
}
if(num == ObjectItems && *words[0] != 0) {
grocery.SetName(words[0]);
grocery.SetBrand(words[1]);
grocery.SetStore(words[2]);
grocery.SetPrice(atof(words[3]));
grocery.SetQuantity(atoi(words[4]));
char *pur_buf = words[5];
if(strcmp(pur_buf, "No") == 0)
grocery.SetPurchasing('N');
else
grocery.SetPurchasing('Y');
grocery.SetLineTotal(atof(words[6]));
grocery_a.SetName(grocery.GetName());
FAU addr = grocery_a.FindObject();
if(addr) {
if(updateall == 0) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + grocery.GetName() + " entry already exists.\n" + \
"Select your choice and click on OK";
ch = wxGetSingleChoiceIndex(sbuf.c_str(), "Importing Objects",
CHArray, ch_array, frame);
}
if(updateall == 1) ch = UPDATE_ALL;
switch(ch) {
case UPDATE_ALL:
updateall = 1;
updates++;
ob.Copy(grocery_a);
if(grocery.FullCompare(ob)) break; // The object has not changed
ob.DeleteObject();
grocery.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + grocery.GetName();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case UPDATE_SKIP:
break;
case UPDATE_ENTRY:
updates++;
ob.Copy(grocery_a);
if(grocery.FullCompare(ob)) break; // The object has not changed
ob.DeleteObject();
grocery.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + grocery.GetName();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case QUIT_THIS:
textWin << "Import cancled." << "\n";
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
sllist.Clear();
return;
default:
break;
}
if(updateall == 1) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + grocery.GetName();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
}
else {
// Nothing to do
}
}
else {
// Ensure that the template does not get added to the file
if(CaseICmp(KeyName, words[0]) != 0) {
FAU addr = grocery.AddObject(0); // Write the object to the file
imports++;
if(!addr) {
textWin << "Could not add:" << grocery.GetName()
<< " to database" << "\n";
imports--;
}
}
}
}
sllistptr = sllistptr->GetNext();
}
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
sllist.Clear();
}
void BackUp(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Backing up the database to another file..." << "\n";
char *FileName = wxFileSelector("Backup to file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Backup canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Export canceled." << "\n";
return;
}
if(!wxRemoveFile(FileName)) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
}
POD newdb(FileName, FileName);
int items = 0;
Grocery grocery(&newdb);
Grocery grocery_old(DB);
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
CachePointer nxt(*DB->Index()->GetCache());
BtreeWalkerb tw(DB->Index(), btINORDER);
nxt = DB->Index()->GetRoot();
while((__LWORD__)nxt != 0) {
nxt = tw.Next();
if((__LWORD__)nxt) {
for(int i = 0; i < nxt->cnt; i++) {
grocery_old.ReadObject(nxt->entry[i].object_address);
grocery.Copy(grocery_old);
grocery.AddObject(0);
items++;
}
}
}
textWin << "Backed up " << items << " objects to " << FileName << "\n";
}
void Merge(MyTextWindow &textWin)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
// wxWindows single choice index box setup
int ch = -1;
const int CHArray = 4;
char *ch_array[CHArray] = {
"Update this entry",
"Skip this entry",
"Update all entries without prompting",
"Quit this merge"
};
enum ICHOICES {
UPDATE_ENTRY,
UPDATE_SKIP,
UPDATE_ALL,
QUIT_THIS
};
textWin.Clear();
textWin << "Merging the contents of another database..." << "\n";
char *FileName = wxFileSelector("Merge from file:", NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Merge canceled." << "\n";
return; // No vaild file name
}
POD newdb(FileName, FileName);
Grocery grocery(&newdb);
Grocery grocery_a(DB);
Grocery ob(DB);
FAU existing;
FAU addr;
UString sbuf;
int imports = 0;
int updates = 0;
int updateall = 0;
FAU oa; // Object Address
VBlockHeader vb; // Variable Block Header
ObjectHeader oh; // Object Header
FAU vbdfileEOF = newdb.OpenDatabase()->GetEOF();
addr = 0;
addr = newdb.OpenDatabase()->FindFirstVB(addr); // Search the entire file
if(addr == 0) {
textWin << "No variable blocks found in file: " << FileName << "\n";
return;
}
textWin << "Merging..." << "\n";
while(1) {
if(addr >= vbdfileEOF) break;
newdb.OpenDatabase()->Read(&vb, sizeof(VBlockHeader), addr);
if(vb.CkWord == CheckWord) {
if((__SBYTE__)vb.VBStatus == NormalVB) {
oa = addr + sizeof(VBlockHeader);
newdb.OpenDatabase()->Read(&oh, sizeof(ObjectHeader), oa);
if(oh.ClassID == grocery.GetClassID()) {
grocery.ReadObject(oa);
grocery_a.SetName(grocery.GetName());
existing = grocery_a.FindObject();
if(existing) {
if(updateall == 0) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + grocery_a.GetName() + \
" entry already exists.\n" + \
"Select your choice and click on OK";
ch = wxGetSingleChoiceIndex(sbuf.c_str(), "Importing Objects",
CHArray, ch_array, frame);
}
if(updateall == 1) ch = UPDATE_ALL;
switch(ch) {
case UPDATE_ALL:
updateall = 1;
updates++;
ob.Copy(grocery);
if(grocery.FullCompare(ob)) break; // Object has not changed
ob.DeleteObject();
ob.Copy(grocery);
ob.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + grocery.GetName();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case UPDATE_SKIP:
break;
case UPDATE_ENTRY:
updates++;
ob.Copy(grocery);
if(grocery.FullCompare(ob)) break; // Object has not changed
ob.DeleteObject();
ob.Copy(grocery);
ob.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + grocery.GetName();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case QUIT_THIS:
textWin << "Merge cancled." << "\n";
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
return;
default:
break;
}
if(updateall == 1) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + grocery.GetName();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
}
else {
// Nothing to do
}
}
else {
grocery_a.Copy(grocery);
FAU rvaddr = grocery_a.AddObject(0); // Write object to the file
imports++;
if(!rvaddr) {
textWin << "Could not add:" << grocery.GetName()
<< " to database" << "\n";
imports--;
}
}
}
}
addr = addr + vb.Length; // Goto the next variable block
}
else {
addr = newdb.OpenDatabase()->VBSearch(addr);
if(!addr) break;
}
}
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
}
void CreateTemplate(MyTextWindow &textWin)
{
const char dchar = '\t'; // Text delimiter
textWin.Clear();
textWin << "Creating template file delimited by tabs..." << "\n";
char *FileName = wxFileSelector("Template file to create:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Creating template canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Creating template canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Creating template file: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
ASPrint(KeyName, stream, strlen(KeyName));
stream << dchar;
ASPrint(M2Name, stream, strlen(M2Name));
stream << dchar;
ASPrint(M3Name, stream, strlen(M3Name));
stream << dchar;
ASPrint(M4Name, stream, strlen(M4Name));
stream << dchar;
ASPrint(M5Name, stream, strlen(M5Name));
stream << dchar;
ASPrint(M6Name, stream, strlen(M6Name));
stream << dchar;
ASPrint(M7Name, stream, strlen(M7Name));
stream << asLineFeed;
textWin << "Finished." << "\n";
stream.close();
}
void ASCIIPrintAll(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Printing database to ASCII file..." << "\n";
int yn;
if(DB->RebuildIndex()) {
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
if(displaying_list) {
yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
}
else
yn = wxNO;
if(yn == wxNO) LoadIndexKeys(as_print_all);
if(dllist->IsEmpty()) LoadIndexKeys(as_print_all);
if(yn == wxYES && as_print_all == 0) ReOrderDisplayList();
char *FileName = wxFileSelector("Print database to file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "ASCII print canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "ASCII print canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Printing to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
textWin << "Printing..." << "\n";
Grocery grocery(DB);
PrintItemBar(stream);
dllistptr = dllist->GetFront();
while(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
PrintLineByLine(grocery, stream);
dllistptr = dllistptr->GetNext();
}
textWin << "Finished." << "\n";
stream.close();
}
void PrintItemBar(ofstream &stream)
{
int i = 0;
ASPrint(KeyName, stream, StringOffset+1);
ASPrint(M2Name, stream, StringOffset+1);
ASPrint(M3Name, stream, StringOffset+1);
ASPrint(M4Name, stream, StringOffset+1);
ASPrint(M5Name, stream, StringOffset);
ASPrint(M7Name, stream, StringOffset+1);
stream << asLineFeed;
i = 0;
while (i++ < PrintColsSpec-1) stream << '=';
stream << asLineFeed;
}
void PrintLineByLine(Grocery &grocery, ofstream &stream)
{
int i;
double price, line_total;
long quantity;
char sbuffer[sbuffer_len];
ASPrint(grocery.GetName(), stream, StringOffset+1);
ASPrint(grocery.GetBrand(), stream, StringOffset+1);
ASPrint(grocery.GetStore(), stream, StringOffset+1);
price = grocery.GetPrice();
sprintf(sbuffer, "%.2f", price);
ASPrint(sbuffer, stream, StringOffset+1);
quantity = grocery.GetQuantity();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%d", quantity);
ASPrint(sbuffer, stream, StringOffset+1);
line_total = grocery.GetLineTotal();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%.2f", line_total);
ASPrint(sbuffer, stream, StringOffset+1);
stream << asLineFeed;
i = 0;
while (i++ < PrintColsSpec-1) stream << '-';
stream << asLineFeed;
}
void CompareIndexFile(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Comparing the index file to the data file..." << "\n";
Grocery grocery(DB);
int rv = grocery.CompareIndex();
if(!rv) {
textWin << "The index file does not match the data file!" << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
textWin << "The index file checks good." << "\n";
}
void RebuildIndexFile(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Rebuilding the index file..." << "\n";
UString sbuf;
char *FileName = wxFileSelector("Enter name for new index file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Rebuild canceled." << "\n";
return; // No vaild file name
}
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Rebuild canceled." << "\n";
return;
}
if(!wxRemoveFile(FileName)) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
}
Grocery grocery(DB);
int rv = grocery.RebuildIndexFile(FileName);
if(!rv) {
textWin << "The index file was not rebuilt!" << "\n";
return;
}
textWin << "The index file was rebuilt." << "\n";
textWin << "A new index file named:\n"
<< FileName << " was created." << "\n";
}
void ViewTotals(MyTextWindow &textWin)
{
textWin.Clear();
if(view_all == 0)
textWin << "Viewing total cost of objects selected for purchase." << "\n";
else
textWin << "Viewing total cost of all objects." << "\n";
if(view_all == 0) {
LoadIndexKeys(0);
}
else {
LoadIndexKeys(1);
}
int i;
char sbuffer[sbuffer_len];
sprintf(sbuffer, "TOTAL BEFORE TAX = $%.2f", grand_total);
textWin << "\n";
textWin << sbuffer << "\n";
if(sales_tax <= 0) {
textWin << "\n";
textWin << "No sales tax value set in config file." << "\n";
textWin << "\n";
return;
}
double tax_percent = sales_tax / 100;
double tax = tax_percent * grand_total;
double tax_total = grand_total;
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "SALES TAX = $%.2f", tax);
textWin << "\n";
textWin << sbuffer << "\n";
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
tax_total += tax;
sprintf(sbuffer, "GRAND TOTAL = $%.2f", tax_total);
textWin << "\n";
textWin << sbuffer << "\n";
textWin << "\n";
}
void SetPurchasing(MyTextWindow &textWin, char purchasing)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
textWin.Clear();
if(purchasing == 'Y' || purchasing == 'y')
textWin << "Purchasing all objects in the database." << "\n";
else
textWin << "Setting all objects for purchase to no." << "\n";
Grocery grocery(DB);
CachePointer nxt(*DB->Index()->GetCache());
BtreeWalkerb tw(DB->Index(), btLVLORDER);
nxt = DB->Index()->GetRoot();
while((__LWORD__)nxt != 0) {
nxt = tw.Next();
if((__LWORD__)nxt) {
for(int i = 0; i < nxt->cnt; i++) {
grocery.ReadObject(nxt->entry[i].object_address);
grocery.SetPurchasing(purchasing);
grocery.SaveChanges();
}
}
}
}
int PrintPSItemBar(ofstream &stream, PostScriptDrv &psdrv,
int x_offset, int char_offset, int cell_len)
{
psdrv.PrintLine((char *)KeyName, cell_len, stream);
x_offset += char_offset;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M2Name, cell_len, stream);
x_offset += char_offset;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M3Name, cell_len, stream);
x_offset += char_offset;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M4Name, cell_len, stream);
x_offset += char_offset;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M5Name, cell_len, stream);
x_offset += char_offset;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M7Name, cell_len, stream);
x_offset += char_offset;
return x_offset;
}
void PostScriptPrint(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Printing database to PostScript file..." << "\n";
int yn, i;
if(DB->RebuildIndex()) {
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
// Setup the default values for user configurable PostScript parameters
int cell_len = 19;
double font_size = 7;
int orientation = 0;
const int DocNameLen = 255;
char psDocName[DocNameLen];
for(i = 0; i < DocNameLen; i++) psDocName[i] = 0;
strcpy(psDocName, ProgramName);
PostScriptDrv::PSPaperSizes paper_code = PostScriptDrv::LETTER_SIZE;
PostScriptDrv::PSFonts item_font = PostScriptDrv::COURIER_BOLD_OBLIQUE;
PostScriptDrv::PSFonts cell_font = PostScriptDrv::COURIER;
// Load the PostScript configuration from the config file
char *CurrentCfgFile;
char *CfgFile;
Config *CfgData = new Config;
int int_val = 0;
double dfp_val = 0;
char *str_val = 0;
// Look for CfgFile name in environment
if((CurrentCfgFile = getenv(EnvSetting)) == 0)
CfgFile = (char *)DefaultCfgFile;
else
CfgFile = CurrentCfgFile;
int FileStatus = CfgData->Load((char *)CfgFile);
if(FileStatus) { // Found a valid config file
// *********************************************************** //
// Add all PostScript config file entries here
// *********************************************************** //
int_val = CfgData->GetIntValue("CellLength");
if(int_val > 0) cell_len = int_val;
dfp_val = CfgData->GetDFPValue("FontSize");
if(dfp_val > 0) font_size = dfp_val;
str_val = CfgData->GetStrValue("Orientation");
if(str_val != 0) {
if(strcmp(str_val, "PORTRAIT") == 0) orientation = 0;
str_val = 0;
}
str_val = CfgData->GetStrValue("PaperSize");
if(str_val != 0) {
if(strcmp(str_val, "LETTER") == 0)
paper_code = PostScriptDrv::LETTER_SIZE;
if(strcmp(str_val, "LEGAL") == 0)
paper_code = PostScriptDrv::LEGAL_SIZE;
if(strcmp(str_val, "TABLOID") == 0)
paper_code = PostScriptDrv::TABLOID_SIZE;
if(strcmp(str_val, "A3") == 0) paper_code = PostScriptDrv::A3_SIZE;
if(strcmp(str_val, "A4") == 0) paper_code = PostScriptDrv::A4_SIZE;
str_val = 0;
}
str_val = CfgData->GetStrValue("ItemBarFont");
if(str_val != 0) {
if(strcmp(str_val, "COURIER") == 0)
item_font = PostScriptDrv::COURIER;
if(strcmp(str_val, "COURIER_BOLD") == 0)
item_font = PostScriptDrv::COURIER_BOLD;
if(strcmp(str_val, "COURIER_OBLIQUE") == 0)
item_font = PostScriptDrv::COURIER_OBLIQUE;
if(strcmp(str_val, "COURIER_BOLD_OBLIQUE") == 0)
item_font = PostScriptDrv::COURIER_BOLD_OBLIQUE;
str_val = 0;
}
str_val = CfgData->GetStrValue("CellFont");
if(str_val != 0) {
if(strcmp(str_val, "COURIER") == 0)
cell_font = PostScriptDrv::COURIER;
if(strcmp(str_val, "COURIER_BOLD") == 0)
cell_font = PostScriptDrv::COURIER_BOLD;
if(strcmp(str_val, "COURIER_OBLIQUE") == 0)
cell_font = PostScriptDrv::COURIER_OBLIQUE;
if(strcmp(str_val, "COURIER_BOLD_OBLIQUE") == 0)
cell_font = PostScriptDrv::COURIER_BOLD_OBLIQUE;
}
str_val = CfgData->GetStrValue("psDocumentName");
if(str_val != 0) {
for(i = 0; i < DocNameLen; i++) psDocName[i] = 0;
strcpy(psDocName, str_val);
}
// *********************************************************** //
}
CfgData->UnLoad(); // Unload the Config file from memory
if(displaying_list) {
yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
}
else
yn = wxNO;
if(yn == wxNO) LoadIndexKeys(ps_print_all);
if(dllist->IsEmpty()) LoadIndexKeys(ps_print_all);
if(yn == wxYES && ps_print_all == 0) ReOrderDisplayList();
char *FileName = wxFileSelector("Print database to PostScript file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "PostScript print canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "PostScript print canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Printing to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
textWin << "Printing..." << "\n";
PostScriptDrv psdrv;
psdrv.Copies(1);
// Setup the PostScript driver
psdrv.SetPaperSize(paper_code);
psdrv.SetFont(cell_font, font_size);
psdrv.UseHeader();
if(orientation == 1) psdrv.LandScapeMode();
psdrv.SetDocumentName(psDocName);
char time_buf[255]; // Buffer used to hold time/date string
GetSystemTime(time_buf);
psdrv.SetDateString(time_buf);
psdrv.DocumentSetup();
psdrv.Prologue(stream);
psdrv.MediaSetup(stream);
Grocery grocery(DB);
double price, line_total;
long quantity;
char sbuffer[sbuffer_len];
int char_offset = int((cell_len + 1) * psdrv.CharWidth());
int x_offset;
if(orientation == 0)
x_offset = int(HEADER_OFFSET * PIXELS_PER_INCH);
else
x_offset = PRINTABLE_OFFSET_X;
int lines = 4;
psdrv.StartPage(psdrv.page_count + 1, stream);
psdrv.row = psdrv.StartY();
psdrv.MoveTo(stream, psdrv.StartX(), psdrv.row);
psdrv.ChangeFont(stream, item_font, font_size);
x_offset = PrintPSItemBar(stream, psdrv, x_offset, char_offset, cell_len);
psdrv.ChangeFont(stream, cell_font, font_size);
int line_points;
if(orientation == 0)
line_points = int(x_offset - (HEADER_OFFSET * PIXELS_PER_INCH));
else
line_points = x_offset - PRINTABLE_OFFSET_X;
psdrv.row -= (int)psdrv.FontSize();
lines++;
psdrv.drawThickLine(stream, line_points, psdrv.StartX(), psdrv.row);
psdrv.row -= THICK_LINE_WIDTH + psdrv.FontSize();
lines ++;
dllistptr = dllist->GetFront();
while(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
if(orientation == 0)
x_offset = int(HEADER_OFFSET * PIXELS_PER_INCH);
else
x_offset = PRINTABLE_OFFSET_X;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(grocery.GetName(), cell_len, stream);
x_offset += char_offset;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(grocery.GetBrand(), cell_len, stream);
x_offset += char_offset;
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(grocery.GetStore(), cell_len, stream);
x_offset += char_offset;
price = grocery.GetPrice();
sprintf(sbuffer, "%.2f", price);
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(sbuffer, cell_len, stream);
x_offset += char_offset;
quantity = grocery.GetQuantity();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%d", quantity);
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(sbuffer, cell_len, stream);
x_offset += char_offset;
line_total = grocery.GetLineTotal();
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "%.2f", line_total);
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(sbuffer, cell_len, stream);
x_offset += char_offset;
psdrv.row -= psdrv.FontSize();
lines++;
if(orientation == 0)
line_points = int(x_offset - (HEADER_OFFSET * PIXELS_PER_INCH));
else
line_points = x_offset - PRINTABLE_OFFSET_X;
psdrv.drawLine(stream, line_points, psdrv.StartX(), psdrv.row);
psdrv.row -= LINE_WIDTH + psdrv.FontSize();
lines++; // Increment the line count
if(lines >= psdrv.LinesPerPage()) {
psdrv.EndPage(stream);
psdrv.StartPage(psdrv.page_count + 1, stream);
if(orientation == 0)
x_offset = int(HEADER_OFFSET * PIXELS_PER_INCH);
else
x_offset = PRINTABLE_OFFSET_X;
psdrv.row = psdrv.StartY();
lines = 4;
psdrv.MoveTo(stream, psdrv.StartX(), psdrv.row);
psdrv.ChangeFont(stream, item_font, font_size);
x_offset = PrintPSItemBar(stream, psdrv, x_offset,
char_offset, cell_len);
psdrv.ChangeFont(stream, cell_font, font_size);
if(orientation == 0)
line_points = int(x_offset - (HEADER_OFFSET * PIXELS_PER_INCH));
else
line_points = x_offset - PRINTABLE_OFFSET_X;
psdrv.row -= (int)psdrv.FontSize();
lines++;
psdrv.drawThickLine(stream, line_points, psdrv.StartX(), psdrv.row);
psdrv.row -= THICK_LINE_WIDTH + psdrv.FontSize();
lines ++;
}
dllistptr = dllistptr->GetNext();
}
psdrv.EndPage(stream);
PostScriptPrintTotals(textWin, stream, psdrv);
stream.close();
}
void PostScriptPrintTotals(MyTextWindow &textWin, ofstream &stream,
PostScriptDrv &psdrv)
{
psdrv.StartPage(psdrv.page_count + 1, stream);
double tax_font_size = 15;
psdrv.ChangeFont(stream, PostScriptDrv::COURIER_BOLD, tax_font_size);
psdrv.row = psdrv.StartY();
char sbuffer[sbuffer_len];
psdrv.row -= tax_font_size * 2; // Offset the tax from the header
sprintf(sbuffer, "TOTAL BEFORE TAX = $%.2f", grand_total);
psdrv.MoveTo(stream, psdrv.StartX(), psdrv.row);
psdrv.PrintLine(sbuffer, stream);
if(sales_tax <= 0) {
textWin << "Finished." << "\n";
psdrv.EndPage(stream);
psdrv.Epilogue(stream, psdrv.page_count);
stream.close();
return;
}
double tax_percent = sales_tax / 100;
double tax = tax_percent * grand_total;
double tax_total = grand_total;
int i;
psdrv.row -= tax_font_size * 2;
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "SALES TAX = $%.2f", tax);
psdrv.MoveTo(stream, psdrv.StartX(), psdrv.row);
psdrv.PrintLine(sbuffer, stream);
psdrv.row -= tax_font_size * 2;
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
tax_total += tax;
sprintf(sbuffer, "GRAND TOTAL= $%.2f", tax_total);
psdrv.MoveTo(stream, psdrv.StartX(), psdrv.row);
psdrv.PrintLine(sbuffer, stream);
psdrv.EndPage(stream);
psdrv.Epilogue(stream, psdrv.page_count);
textWin << "Finished." << "\n";
stream.close();
}
#ifdef __USE_MSW_PRINTING__
void page_btn_proc(wxButton& but, wxCommandEvent& event)
// Button procedures for the MSW Page Setup Dialog box
{
long tag = (long)but.GetClientData() ;
if(tag == PAGE_DIALOG_BUTTON_CLOSE) {
wxPageDialog->Show(FALSE);
delete wxPageDialog;
}
if(tag == PAGE_DIALOG_BUTTON_ACCEPT) {
MSWPrintSetup->lines_per_page = LppSlider->GetValue();
MSWPrintSetup->cell_length = CellSlider->GetValue();
MSWPrintSetup->font_size = FsSlider->GetValue();
MSWPrintSetup->orientation = OrientationChoice->GetSelection();
MSWPrintSetup->font = FontChoice->GetSelection();
MSWPrintSetup->lr_margin = LRMSlider->GetValue();
MSWPrintSetup->prev_lines_per_page = LppSlider->GetValue();
MSWPrintSetup->prev_cell_length = CellSlider->GetValue();
MSWPrintSetup->prev_font_size = FsSlider->GetValue();
MSWPrintSetup->prev_orientation = OrientationChoice->GetSelection();
MSWPrintSetup->prev_font = FontChoice->GetSelection();
MSWPrintSetup->prev_lr_margin = LRMSlider->GetValue();
}
if(tag == PAGE_DIALOG_BUTTON_CANCEL) {
LppSlider->SetValue(MSWPrintSetup->prev_lines_per_page);
CellSlider->SetValue(MSWPrintSetup->prev_cell_length);
FsSlider->SetValue(MSWPrintSetup->prev_font_size);
OrientationChoice->SetSelection(MSWPrintSetup->prev_orientation);
FontChoice->SetSelection(MSWPrintSetup->prev_font);
LRMSlider->SetValue(MSWPrintSetup->prev_lr_margin);
}
if(tag == PAGE_DIALOG_BUTTON_DEFAULT) {
LppSlider->SetValue(MSWPrintSetup->default_lines_per_page);
CellSlider->SetValue(MSWPrintSetup->default_cell_length);
FsSlider->SetValue(MSWPrintSetup->default_font_size);
OrientationChoice->SetSelection(MSWPrintSetup->default_orientation);
FontChoice->SetSelection(MSWPrintSetup->default_font);
LRMSlider->SetValue(MSWPrintSetup->default_lr_margin);
}
}
void wGrocPrint::SetFont(int style, int weight)
{
switch(MSWPrintSetup->font) {
case 0:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 1:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxROMAN, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 2:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDECORATIVE,
style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 3:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxMODERN, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 4:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSCRIPT, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 5:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDEFAULT, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
default:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
};
}
void wGrocPrint::SetItemBarFont(int style, int weight)
{
switch(MSWPrintSetup->font) {
case 0:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
break;
case 1:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxROMAN, style, weight);
break;
case 2:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDECORATIVE,
style, weight);
break;
case 3:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxMODERN, style, weight);
break;
case 4:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSCRIPT, style, weight);
break;
case 5:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDEFAULT, style, weight);
break;
default:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
break;
};
}
void wGrocPrint::OnPreparePrinting()
// Called once by the framework before any other demands are made
// of the wxPrintout object.
{
SetFont();
SetItemBarFont();
SetHeaderFont(15, wxSWISS, wxNORMAL, wxBOLD);
}
Bool wGrocPrint::OnPrintPage(int page)
// Called by the framework when a page should be printed.
// Returning FALSE cancels the print job. The application
// can use wxPrintout::GetDC to obtain a device context to
// draw on.
{
wxDC *dc = GetDC();
if(dc) {
DrawTextPage(dc, page);
return TRUE;
}
else
return FALSE;
}
Bool wGrocPrint::OnBeginDocument(int startPage, int endPage)
// Called by the framework at the start of document printing.
// OnBeginDocument is called once for every copy printed.
// The base wxPrintout::OnBeginDocument must be called
// (and the return value checked) from within the overriden
// function, since it calls wxDC::StartDoc.
{
if (!wxPrintout::OnBeginDocument(startPage, endPage))
return FALSE; // Returns FALSE if the print job is canceled
return TRUE;
}
Bool wGrocPrint::HasPage(int pageNum)
// Should be overriden to return TRUE if the document has this page,
// or FALSE if not. Returning FALSE signifies the end of the document.
// By default, HasPage behaves as if the document has only one page.
{
// Calculate the number of pages in this document
int minPage, maxPage, selPageFrom, selPageTo;
GetPageInfo(&minPage, &maxPage, &selPageFrom, &selPageTo);
return (pageNum == minPage) || (pageNum <= maxPage);
}
void wGrocPrint::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom,
int *selPageTo)
// Called by the framework to obtain information from the application
// about minimum and maximum page values that the user can select, and
// the required page range to be printed.
{
if(DB->RebuildIndex()) { // The index files needs to be rebuilt
*minPage = 1;
*selPageFrom = 1;
*selPageTo = 1;
*maxPage = 1;
return;
}
if(print_list == 0) num_objects = LoadIndexKeys(print_all);
if(dllist->IsEmpty()) num_objects = LoadIndexKeys(print_all);
if(displaying_list == 1) {
if(print_all == 0) ReOrderDisplayList();
}
dllistptr = dllist->GetFront();
int lines = num_objects;
int first_page = 1; // Always starting on page one
last_page = 1; // Default is the first page
*minPage = first_page; // Always starting on page one
*selPageFrom = first_page; // Always starting on page one
for(;;) {
if(lines <= MSWPrintSetup->lines_per_page) break;
lines = lines - MSWPrintSetup->lines_per_page;
last_page++; // Increment the page count
}
last_page++; // Reserve a page to print the grand total
*selPageTo = last_page;
*maxPage = last_page;
}
void wGrocPrint::ScaleDC(wxDC *dc)
// Scale the DC so that the printout roughly represents the
// the screen scaling.
{
// Get the page size
GetPageSizeMM(&page_width, &page_height);
// Get the logical pixels per inch of screen and printer
GetPPIScreen(&ppiScreenX, &ppiScreenY);
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
// Scale the DC so that the printout roughly represents the
// the screen scaling.
scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
// Calculate conversion factor for converting millimetres into
// logical units. There are approx. 25.1 mm to the inch. There
// are ppi device units to the inch. Therefore 1 mm corresponds
// to ppi/25.1 device units.
logUnitsFactor = (float)(ppiPrinterX / (scale * 25.1));
// Check real page size in case it is reduced by print preview
int pageWidth, pageHeight;
float w, h;
dc->GetSize(&w, &h);
GetPageSizePixels(&pageWidth, &pageHeight);
// Do not change if printer pageWidth == current DC width
float overallScale = scale * (float)(w/(float)pageWidth);
dc->SetUserScale(overallScale, overallScale);
}
void wGrocPrint::DrawTextPage(wxDC *dc, int page)
// Write page by page with margins, header, and page numbers
{
dc->SetFont(itembarFont); // Set the text font for the item bar
ScaleDC(dc);
start_x = (float)(logUnitsFactor * MSWPrintSetup->lr_margin);
start_y = (float)(logUnitsFactor * MSWPrintSetup->tb_margin);
int end = page * MSWPrintSetup->lines_per_page; // Last line to write
int start = end - MSWPrintSetup->lines_per_page; // First line to write
float textW, textH; // Text width and height
float xpos = start_x;
float ypos = start_y;
int char_offset = int((MSWPrintSetup->cell_length + 1) * char_width);
float x_offset = xpos;
if(page != last_page) { // Do not print item bar on last page
PrintText(dc, (char *)KeyName, MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
dc->GetTextExtent((char *)KeyName, &textW, &textH);
PrintText(dc, (char *)M2Name, MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, (char *)M3Name, MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, (char *)M4Name, MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, (char *)M5Name, MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, (char *)M7Name, MSWPrintSetup->cell_length,
x_offset, ypos);
// Do not draw a line past the member
x_offset += int((strlen(M7Name) + 1) * char_width);
}
ypos += textH;
dc->DrawLine(xpos , ypos, x_offset, ypos);
ypos += mswpLINE_WIDTH;
int lines = 0;
Grocery grocery(DB);
dc->SetFont(printerFont); // Set the text font for the objects
for(int i = 0; i < start; i++) {
if(!dllist->IsHeader(dllistptr))
dllistptr = dllistptr->GetNext();
}
while(!dllist->IsHeader(dllistptr)) {
grocery.ReadObject(dllistptr->Data.object_address);
x_offset = xpos;
ypos += mswpLINE_WIDTH;
PrintText(dc, grocery.GetName(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
dc->GetTextExtent(grocery.GetName(), &textW, &textH);
PrintText(dc, grocery.GetBrand(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, grocery.GetStore(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, (double)grocery.GetPrice(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, (long)grocery.GetQuantity(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
PrintText(dc, (double)grocery.GetLineTotal(), MSWPrintSetup->cell_length,
x_offset, ypos);
// Do not draw a line past the member
x_offset += int((strlen(M7Name) + 1) * char_width);
ypos += textH;
ypos += mswpLINE_WIDTH;
dc->DrawLine(xpos , ypos, x_offset, ypos);
ypos += mswpLINE_WIDTH;
lines++;
if(lines >= MSWPrintSetup->lines_per_page) break;
dllistptr = dllistptr->GetNext();
}
char time_buf[sbuffer_len]; // Buffer used to hold time/date string
GetSystemTime(time_buf); // Part of the PostScript Driver class
WritePageHeader(dc, mswpDocumentName, time_buf);
WritePageNumber(dc, page);
// Print the grand total
if(page == last_page) {
dc->SetFont(headerFont);
char sbuffer[sbuffer_len];
xpos = start_x; ypos = start_y;
sprintf(sbuffer, "TOTAL BEFORE TAX = $%.2f", grand_total);
dc->GetTextExtent(sbuffer, &textW, &textH);
ypos += textH * 2; // Offset text from the page header
PrintText(dc, sbuffer, xpos, ypos);
if(sales_tax <= 0)
return; // No sales tax info in the config file
double tax_percent = sales_tax / 100;
double tax = tax_percent * grand_total;
double tax_total = grand_total;
ypos += textH * 2;
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
sprintf(sbuffer, "SALES TAX = $%.2f", tax);
dc->GetTextExtent(sbuffer, &textW, &textH);
PrintText(dc, sbuffer, xpos, ypos);
ypos += textH * 2; // Offest from header
for(i = 0; i < sbuffer_len; i++) sbuffer[i] = '\0';
tax_total += tax;
sprintf(sbuffer, "GRAND TOTAL = $%.2f", tax_total);
PrintText(dc, sbuffer, xpos, ypos);
}
}
void wGrocPrint::SetHeaderFont(int size, int font, int style, int weight)
// Set the header and page number font type, size, and style
{
headerFont = wxTheFontList->FindOrCreateFont(size, font, style, weight);
}
void wGrocPrint::WritePageHeader(wxDC *dc, char *doc_name, char *doc_date)
// Writes header on top of page. Margin units are in millimetres.
{
dc->SetFont(headerFont);
// Offset the margins to move text above the first line
int leftMargin = MSWPrintSetup->lr_margin / 2;
int topMargin = MSWPrintSetup->tb_margin / 2;
int rightMargin = MSWPrintSetup->lr_margin / 2;
float leftMarginLogical = (float)(logUnitsFactor * leftMargin);
float topMarginLogical = (float)(logUnitsFactor * topMargin);
float rightMarginLogical = (float)(logUnitsFactor* \
(page_width - rightMargin));
float xExtentName, yExtentName, xExtentDate, yExtentDate, xPos, offset;
dc->GetTextExtent(doc_name, &xExtentName, &yExtentName);
if(doc_date != 0) { // Printing document name and date strings
dc->GetTextExtent(doc_date, &xExtentDate, &yExtentDate);
// Draw the document's name left justified
PrintText(dc, doc_name, start_x, topMarginLogical);
// Draw the document's date right justified
if(MSWPrintSetup->orientation == 0) // Landscape printing
offset = (logUnitsFactor * page_width) - \
(logUnitsFactor * (MSWPrintSetup->lr_margin + mswpPRINTABLE_OFFSET_X));
else
offset = (logUnitsFactor * page_width) - \
(logUnitsFactor * (MSWPrintSetup->lr_margin + mswpPRINTABLE_OFFSET_X));
xPos = (float)(offset - xExtentDate);
PrintText(dc, doc_date, xPos, topMarginLogical);
}
else { // Center the document's name
xPos = (float)(((((page_width - leftMargin - rightMargin)/2.0)
+leftMargin)*logUnitsFactor) - (xExtentName/2.0));
PrintText(dc, doc_name, xPos, topMarginLogical);
}
}
void wGrocPrint::WritePageNumber(wxDC *dc, int pagenum)
// Writes page number on bottom of page. Margin units are in millimetres.
{
dc->SetFont(headerFont);
// Offset the margins to move text below the last line
int leftMargin = MSWPrintSetup->lr_margin;
int bottomMargin = MSWPrintSetup->tb_margin;
int rightMargin = MSWPrintSetup->lr_margin;
float leftMarginLogical = (float)(logUnitsFactor * leftMargin);
float bottomMarginLogical = (float)(logUnitsFactor * (page_height - \
bottomMargin));
float rightMarginLogical = (float)(logUnitsFactor*(page_width - \
rightMargin));
float xExtent, yExtent;
char sbuffer[sbuffer_len];
sprintf(sbuffer, "PAGE %d", pagenum);
dc->GetTextExtent(sbuffer, &xExtent, &yExtent);
float xPos = (float)(((((page_width - leftMargin - rightMargin)/2.0)
+leftMargin)*logUnitsFactor) - (xExtent/2.0));
PrintText(dc, sbuffer, xPos, bottomMarginLogical);
}
void wGrocPrint::PrintText(wxDC *dc, char *s, int max_len,
float xpos, float ypos)
// Draw text in the device context.
{
if(s == 0 || max_len <= 0) return;
int slen = strlen(s);
if(slen > max_len) {
char *buf = new char[max_len];
buf[max_len] = '\0';
memmove(buf, s, max_len);
dc->DrawText(buf, xpos, ypos);
delete [] buf;
}
else
dc->DrawText(s, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, char *s, float xpos, float ypos)
// Draw text in the device context.
{
if(s == 0) return;
dc->DrawText(s, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, char c, float xpos, float ypos)
{
char s[1];
s[0] = c; // Copy char into a string buffer
s[1] = '\0'; // Null terminate the string
PrintText(dc, s, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, int i, int max_len,
float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%d", i);
PrintText(dc, sbuffer, max_len, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, long i, int max_len,
float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%d", i);
PrintText(dc, sbuffer, max_len, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, double i, int max_len,
float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%.2f", i);
PrintText(dc, sbuffer, max_len, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, float i, int max_len,
float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%.2f", i);
PrintText(dc, sbuffer, max_len, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, int i, float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%d", i);
PrintText(dc, sbuffer, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, long i, float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%d", i);
PrintText(dc, sbuffer, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, double i, float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%.2f", i);
PrintText(dc, sbuffer, xpos, ypos);
}
void wGrocPrint::PrintText(wxDC *dc, float i, float xpos, float ypos)
{
char sbuffer[sbuffer_len];
sprintf(sbuffer, "%.2f", i);
PrintText(dc, sbuffer, xpos, ypos);
}
#endif // __USE_MSW_PRINTING__
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //